【数据结构】A、B为递减有序的单链表,编写函数,将它们合并成递增有序的单链表,相同元素值只保留一个结点

1.算法思路

  1. 将两单链表合并,常用的方法是归并排序。每次比较两个链表的当前结点值,选择较大的结点值进行插入操作。
  2. 由于是将递减有序的链表变为递增有序的链表,那么可以考虑使用头插法,每次归并排序比较完成后将更大值的结点插入到已排序链表中,然后移动排序链表的头指针指向该结点。

2.定义结构体

typedef struct LNode {
   
   
    int data;
    struct LNode *next;
} LNode, *LinkList;

3.定义函数

3.1 创建单链表

编写函数创建单链表。输入参数为:

  • LinkList A: 单链表的头结点
  • int a[]: 该单链表的元素值
  • length: 元素值的长度
    当i < length时,循环创建结点,并使用尾插法将结点插入到当前链表的最后面,然后将链表尾指针移动至尾部,即当前结点。
void CreateList(LinkList A, int a[], int length) {
   
   
    LNode *s = (LNode *)malloc(sizeof(LNode));
    LNode *tail = A;
    s->next = NULL;
    for(int i=0; i < length; i++) {
   
   
        s = (LNode *)malloc(sizeof(LNode));//创建新结点
        s->data = a[i];
        s->next = NULL;
        tail->next = s;
        tail = tail->next;
    }
}

3.2 合并单链表

  1. 首先创建链表头结点C,它将指向已排好序的链表头结点,每次使用头插法插入新结点后都将指向此时的头结点,即新结点。
  2. 创建工作指针p,q分别指向A和B的首个数据结点。判断p,q是否为空。如果有链表为空,则返回NULL。这里假定两个链表都不为空时才进行排序,否则结束程序。
  3. 当p,q都不为空时,遍历A,B链表,比较结点值,进行如下判断:
    • p->data == q->data: 说明两结点值重复,因此选择删除一个结点,头插另一个结点。这里选择插入p结点而删除q结点。首先使用指针s只想当前结点p,然后将p结点向后移动,之后修改相应指针实现p的头插。然后将s指向q,并让q向后移动,再释放s。
    • p->data > q->data: 此时选择更大的结点即p将其插入到排序链表中,然后p后移,比较新的p和q。
    • p->data < q->data: 此时选择更大的结点即q将其插入到排序链表中,然后q后移,比较新的p和q。
  4. 当A或B遍历完成时,上述循环退出。此时判断p,q哪个指针为空。使用头插法将未空指针后面的剩余结点插入到排序链表。
LinkList MergeList(LinkList A, LinkList B) {
   
   
    //C用于指向以合并链表的头结点
    LinkList C = (LinkList)malloc(sizeof(LNode));
    C->next = NULL;
    //p,q用于遍历两个链表,s用于指向当前结点更大的结点
    LNode *p = A->next, *q = B->next, *s = NULL;
    if(!p || !q) {
   
   
        printf("链表为空!\n");
        return NULL;
    }
    while(p && q) {
   
   //p,q都不为空,开始比较
        if(p->data == q->data) {
   
   //p,q相等,删除一个结点
            //首先将一个结点头插到当前链表中
            s = p;
            p = p
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天进步一点丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值