首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将两个有序链表合并为一个有序链表

将两个有序链表合并为一个有序链表
EN

Stack Overflow用户
提问于 2013-07-25 04:31:33
回答 3查看 5.1K关注 0票数 0

我一直在尝试编写一段代码,将两个整数有序列表合并为一个整数有序列表。

函数ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )应该接收指向两个列表中每个列表的第一个节点的指针。

除了合并功能之外,其他所有功能似乎都可以正常工作。

问题似乎是它去掉了较短列表中的最后一个元素。

代码语言:javascript
复制
//12.7 merge two ordered lists into one ordered list
#include <stdio.h>
#include <stdlib.h>

struct listNode
{
    int data;
    struct listNode *nextPtr;
};

    typedef struct listNode ListNode;
    typedef ListNode *ListNodePtr;

    void insert( ListNodePtr *sPtr, int value );
    ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr );
    int isEmpty( ListNodePtr currentPtr );
    void printList( ListNodePtr currentPtr );
    void instructions(void);

int main(void)
{
    ListNodePtr startPtr1 = NULL;
    ListNodePtr startPtr2 = NULL;

    unsigned int choice;
    int item;

    instructions();
    printf("\n?");
    scanf("%u",&choice);

    while (choice != 4)
    {
        switch (choice)
        {
        case 1:
            printf("Enter a character into list 1:\n");
            scanf("\n%d",&item);
            insert( &startPtr1, item );
            printList( startPtr1 );
            break;
        case 2:
            printf("Enter a character into list 2:\n");
            scanf("\n%d",&item);
            insert( &startPtr2, item );
            printList( startPtr2 );
            break;
        case 3:
            if (isEmpty(startPtr1) && isEmpty(startPtr2))
            {
                puts("Both lists are empty.");
            }
            else if (isEmpty(startPtr1))
            {
                puts("List 1 is empty.");
            }
            else if (isEmpty(startPtr2))
            {
                puts("List 2 is empty.");
            }
            else
            {
            printList( startPtr1 );
            printList( startPtr2 );
            puts("Merged list:");
            printList( merge( startPtr1, startPtr2 ) );
            }
            break;
        default:
            printf("Invalid choice.\n");
            instructions();
            break;
        }
        printf("\n?");
        scanf("%u",&choice);
    }
        puts("End of run.");
}

void instructions(void)
{
    printf("Enter your choice:\n"
    "   1 to insert an number into list 1.\n"
    "   2 to insert an number into list 2.\n"
    "   3 to merge and order list 1 and list 2.\n"
    "   4 to end.");
}

void insert( ListNodePtr *sPtr, int value )
{
    ListNodePtr newPtr;
    ListNodePtr previousPtr;
    ListNodePtr currentPtr;

    newPtr = (ListNodePtr)malloc(sizeof(ListNode));

    if (newPtr != NULL)
    {
        newPtr->data = value;
        newPtr->nextPtr = NULL;

        previousPtr = NULL;
        currentPtr = *sPtr;

        while (currentPtr != NULL && value > currentPtr->data)
        {
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
        }

        if (previousPtr == NULL)
        {
                newPtr->nextPtr = *sPtr;
                *sPtr = newPtr;
        }
        else
        {
            previousPtr->nextPtr = newPtr;
            newPtr->nextPtr = currentPtr;
        }
    }
    else
    {
            printf( "%d not inserted. No memory available.", value );
    }
}

ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )
{
    ListNode merge; 
    ListNodePtr mergePtr = &merge;

    //PROBLEM: merge.nextPtr will be missing second to last element 
    //in final merged list

    while ( xPtr->nextPtr != NULL && yPtr->nextPtr != NULL)
    {
        if ( xPtr->data < yPtr->data)
        {
            mergePtr->nextPtr = xPtr;
            xPtr = xPtr->nextPtr;
            mergePtr = mergePtr->nextPtr;

        }//end if
        if ( yPtr->data < xPtr->data)
        {
            mergePtr->nextPtr = yPtr;
            yPtr = yPtr->nextPtr;
            mergePtr = mergePtr->nextPtr;
        }//end if
    }//end of while
    if ( xPtr->nextPtr == NULL )
    {
        mergePtr->nextPtr = yPtr;
    }
    if ( yPtr->nextPtr == NULL )
    {
        mergePtr->nextPtr = xPtr;
    }   
    return merge.nextPtr;
}//end of function merge


int isEmpty( ListNodePtr sPtr )
{
    return sPtr == NULL;
}

void printList( ListNodePtr currentPtr )
{
    if ( isEmpty(currentPtr) )
    {
        puts("List is empty");
    }
    else
    {
        while ( currentPtr != NULL )
        {
            printf("%d --> ", currentPtr->data);
            currentPtr = currentPtr->nextPtr;
        }
        puts("NULL");
    }
}

有人能解决这个问题吗?我已经学习C编程语言一个半月了。

EN

回答 3

Stack Overflow用户

发布于 2013-07-25 06:47:11

我稍微修改了一下你的代码,它运行的很完美!

代码语言:javascript
复制
//12.7 merge two ordered lists into one ordered list
#include <stdio.h>
#include <stdlib.h>

struct listNode
{
   ! int data;
    struct listNode *nextPtr;
};

    typedef struct listNode ListNode;
    typedef ListNode *ListNodePtr;

    void insert( ListNodePtr *sPtr, int value );
    ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr );
    int isEmpty( ListNodePtr currentPtr );
    void printList( ListNodePtr currentPtr );
    void instructions(void);

int main(void)
{
    ListNodePtr startPtr1 = NULL;
    ListNodePtr startPtr2 = NULL;

    unsigned int choice;
    int item;

    instructions();
    printf("\n?");
    scanf("%u",&choice);

    while (choice != 4)
    {
        switch (choice)
        {
        case 1:
            printf("Enter a character into list 1:\n");
            scanf("\n%d",&item);
            insert( &startPtr1, item );
            printList( startPtr1 );
            break;
        case 2:
            printf("Enter a character into list 2:\n");
            scanf("\n%d",&item);
            insert( &startPtr2, item );
            printList( startPtr2 );
            break;
        case 3:
            if (isEmpty(startPtr1) && isEmpty(startPtr2))
            {
                puts("Both lists are empty.");
            }
            else if (isEmpty(startPtr1))
            {
                puts("List 1 is empty.");
            }
            else if (isEmpty(startPtr2))
            {
                puts("List 2 is empty.");
            }
            else
            {
            printList( startPtr1 );
            printList( startPtr2 );
            puts("Merged list:");
            printList( merge( startPtr1, startPtr2 ) );
            }
            break;
        default:
            printf("Invalid choice.\n");
            instructions();
            break;
        }
        printf("\n?");
        scanf("%u",&choice);
    }
        puts("End of run.");
}

void instructions(void)
{
    printf("Enter your choice:\n"
    "   1 to insert an number into list 1.\n"
    "   2 to insert an number into list 2.\n"
    "   3 to merge and order list 1 and list 2.\n"
    "   4 to end.");
}

void insert( ListNodePtr *sPtr, int value )
{
    ListNodePtr newPtr;
    ListNodePtr previousPtr;
    ListNodePtr currentPtr;

    newPtr = (ListNodePtr)malloc(sizeof(ListNode));

    if (newPtr != NULL)
    {
        newPtr->data = value;
        newPtr->nextPtr = NULL;

        previousPtr = NULL;
        currentPtr = *sPtr;

        while (currentPtr != NULL && value > currentPtr->data)
        {
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
        }

        if (previousPtr == NULL)
        {
                newPtr->nextPtr = *sPtr;
                *sPtr = newPtr;
        }
        else
        {
            previousPtr->nextPtr = newPtr;
            newPtr->nextPtr = currentPtr;
        }
    }
    else
    {
            printf( "%d not inserted. No memory available.", value );
    }
}

ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )
{
    ListNode merge; 
    ListNodePtr begin, mergePtr = &merge;          //here
    begin = mergePtr;                              //here
    //PROBLEM: merge.nextPtr will be missing second to last element 
    //in final merged list

    while ( xPtr != NULL && yPtr != NULL)      //here 2   now I deal with the last of short link!
    {
        if ( xPtr->data < yPtr->data)
        {
            mergePtr->nextPtr = xPtr;
            xPtr = xPtr->nextPtr;
            mergePtr = mergePtr->nextPtr;

        }//end if
        else// ( yPtr->data < xPtr->data)      //here for yPtr->data == xPtr->data
        {
            mergePtr->nextPtr = yPtr;
            yPtr = yPtr->nextPtr;
            mergePtr = mergePtr->nextPtr;
        }//end if
    }//end of while
    if ( xPtr != NULL )                          //here 2
    {
        mergePtr->nextPtr = xPtr;
    }
    if ( yPtr != NULL )                           //here 2
    {
        mergePtr->nextPtr = yPtr;
    }   
    return begin->nextPtr;                         //here
}//end of function merge


int isEmpty( ListNodePtr sPtr )
{
    return sPtr == NULL;
}

void printList( ListNodePtr currentPtr )
{
    if ( isEmpty(currentPtr) )
    {
        puts("List is empty");
    }
    else
    {
        while ( currentPtr != NULL )
        {
            printf("%d --> ", currentPtr->data);
            currentPtr = currentPtr->nextPtr;
        }
        puts("NULL");
    }
}
票数 1
EN

Stack Overflow用户

发布于 2013-07-25 04:38:42

由于您正在检查下一个值是否为null,因此当您命中最后一个值时,您将中断merge while循环。在这个while循环之外,您应该将另一个列表追加到另一个列表中。因此,如果List1用完了所有元素,而List2还有3个元素,那么不用遍历List2,只需生成(end of List1)->next =(您在List2中停下来的地方)。

另外,不要在merge函数中返回。你不需要这么做。因为yoru列表已经占用了空间,所以你只需要切换它们的指针所指向的位置。一旦完成了所有指针,只需像通常那样从函数返回一个访问列表1/列表2(除非您需要找出哪个列表包含第一个指针,所以只返回1或2)

此外,您也不会将merge设置为我不认为的值

票数 0
EN

Stack Overflow用户

发布于 2013-07-25 06:24:25

代码语言:javascript
复制
ListNodePtr merge( ListNodePtr xPtr, ListNodePtr yPtr )
{
    ListNode merge; 
    ListNodePtr mergePtr = &merge;

    while ( xPtr != NULL && yPtr != NULL)
    {
        if ( xPtr->data < yPtr->data)
        {
            mergePtr->nextPtr = xPtr;
            xPtr = xPtr->nextPtr;
            mergePtr = mergePtr->nextPtr;

        } else if ( yPtr->data < xPtr->data)//need else because 1 loop 2 ecxecute merge
        {
            mergePtr->nextPtr = yPtr;
            yPtr = yPtr->nextPtr;
            mergePtr = mergePtr->nextPtr;
        }//end if
        //nothing case of (yPtr->data == xPtr->data)
    }//end of while
    if ( xPtr == NULL )
    {
        mergePtr->nextPtr = yPtr;
    }
    if ( yPtr == NULL )
    {
        mergePtr->nextPtr = xPtr;
    }   
    return merge.nextPtr;
}//end of function merge
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17844254

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档