合并链表

例2.3

有两个链表LA和LB,其元素均为非递减有序排列,编写算法,将它们合并成一个链表LC,要求LC也是非递减有序排列。
例如,LA=(2,2,3),LB=(1,3,3,4),则LC=(1,2,2,3,3,3,4)。

#include <stdio.h>
#include <stdlib.h>
#define MAX 100

typedef struct Node
{
    int num;
    struct Node *next;
} Node, *LinkList;

//使用指针的指针进行的初始化,l对应二级指针,*l对应一级指针
void InitLinkList(LinkList *l)
{
    *l = (LinkList)malloc(sizeof(Node)); //建立头结点
    (*l)->next = NULL;                   //建立空的单链表
}

// 头插法,用好头指针控制新节点
void CreateFromHead(LinkList l)
{
    LinkList n;
    int number;
    int flag = 1;
    while (flag)
    {
        scanf("%d", &number);
        if (number != -1)
        {
            n = (LinkList)malloc(sizeof(Node));
            n->num = number;
            n->next = l->next;
            l->next = n;
        }
        else
            flag = 0;
    }
}

// 尾插法,设置一个尾指针进行控制
void CreateFromTail(LinkList l)
{
    LinkList n = l, s;
    int number;
    int flag = 1;
    while (flag)
    {
        scanf("%d", &number);
        if (number != -1)
        {
            s = (LinkList)malloc(sizeof(Node));
            n->next = s;
            n = s; //这里的n相当于尾指针,一直指向链表末尾
            s->next = NULL;
            s->num = number;
        }
        else
            flag = 0;
    }
}

int DeleteLinkList(LinkList l, int index)
{
    int number;
    LinkList temp = l, node;
    for (int i = 0; i < index - 1; i++)
        temp = temp->next;
    node = temp;
    temp = temp->next;
    return number;
}

void PrintLinkList(LinkList l)
{
    LinkList temp = l;
    while (temp->next)
    {
        temp = temp->next;
        printf("%d ", temp->num);
    }
}

// void mergeList(LinkList LA, LinkList LB, LinkList LC)
// {
//     LinkList s;
//     LinkList n = LC;
//     LA = LA->next;
//     LB = LB->next;
//     while (LA && LB)
//     {
//         s = (LinkList)malloc(sizeof(Node));
//         if (LA->num < LB->num)
//         {
//             s->num = LA->num;
//             LA = LA->next;
//         }
//         else
//         {
//             s->num = LB->num;
//             LB = LB->next;
//         }
//         n->next = s;
//         n = s;
//         s->next = NULL;
//     }

//     while (LA)
//     {
//         s = (LinkList)malloc(sizeof(Node));
//         s->num = LA->num;
//         LA = LA->next;
//         n->next = s;
//         n = s;
//         s->next = NULL;
//     }

//     while (LB)
//     {
//         s = (LinkList)malloc(sizeof(Node));
//         s->num = LB->num;
//         LB = LB->next;
//         n->next = s;
//         n = s;
//         s->next = NULL;
//     }
// }

void mergeList(LinkList LA, LinkList LB, LinkList LC)
{
    LinkList pa = LA->next;
    LinkList pb = LB->next;
    LinkList pc = LC;

    while (pa && pb)
    {
        LinkList s = (LinkList)malloc(sizeof(Node));
        if (!s)
        {
            printf("内存分配失败\n");
            exit(1);
        }

        if (pa->num < pb->num)
        {
            s->num = pa->num;
            pa = pa->next;
        }
        else
        {
            s->num = pb->num;
            pb = pb->next;
        }

        pc->next = s;
        pc = s;
        s->next = NULL;
    }

    // 处理剩余元素,哪个有剩余,直接剩余所有的连接上去
    if (pa)
    {
        pc->next = pa;
    }
    else
    {
        pc->next = pb;
    }
}

int main()
{
    LinkList LA, LB, LC;
    InitLinkList(&LA);
    InitLinkList(&LB);
    InitLinkList(&LC);
    CreateFromTail(LA);
    CreateFromTail(LB);
    mergeList(LA, LB, LC);
    PrintLinkList(LC);
    return 0;
}

总结

这里对于合并函数mergeList的改进:
1.改用pa,pb,pc控制LA,LB,LC,防止原有链表头指针的改变。
2.对于剩余部分的处理,不需要使用循环,直接将剩余链表部分整个接上去即可。

posted @ 2023-09-10 11:04  DawnTraveler  阅读(14)  评论(0编辑  收藏  举报