合并两个有序链表

本文深入解析了两种有序链表合并算法:迭代法和递归法。通过具体实例,详细阐述了每种方法的实现步骤及核心代码,帮助读者理解链表结构的处理技巧。文章还特别提醒了在编程过程中易犯的错误,如处理空列表和指针操作的注意事项。

解法一:整个过程就是依次比较,谁小指谁。

错误记录:

  1. ret=p; //把表头保存着 别丢了
  2. if(!a) return b; //要考虑输入空列表的情况
  3. p->next = b; //只对指针操作就行,不要对值进行操作p->val = b->val
  4. p->next = a?a:b; //把之后的全接上

比较典型的代码块,链接链表的过程,先找到指针p的下一个节点p->next = b;将p移动到下一个节点的位置上(让p指向下一个节点):

        if(a->val >= b->val){
            p->next = b;    //只对指针操作就行,不要对值进行操作p->val = b->val
            p = p->next;    //这部分很典型,链表连接的操作记住了 
            b = b->next;
        }
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    struct ListNode *a = l1;
    struct ListNode *b = l2;
    struct ListNode *p = NULL ;
    struct ListNode *ret = NULL ;

     // 先让p指向头节点
    if (a && b){  
        if(a->val >= b->val){
            p = b;
            b = b->next;
        }
        else{
            p = a;
            a = a->next;
        }
        ret=p;        //把表头保存着 别丢了
    }
    else{
        if(!a) return b;      //要考虑输入空列表的情况
        else return a;
    }
    while (a && b){
        if(a->val >= b->val){
            p->next = b;    //只对指针操作就行,不要对值进行操作p->val = b->val
            p = p->next;    //这部分很典型,链表连接的操作记住了 
            b = b->next;
        }
        else{
            p->next = a;
            p = p->next;
            a = a->next;
        }
    }
    p->next = a?a:b;  //把之后的全接上
    return ret;
}

解法二:递归解法

然鹅并不能看懂

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    if(l1==NULL)
        return l2;
    if(l2==NULL)
        return l1;
    if(l1->val < l2->val){
        l1->next = mergeTwoLists(l1->next,l2);
        return l1;
    }else{
        l2->next = mergeTwoLists(l1,l2->next);
        return l2;
    }
}

又做了一次

02-线性结构1 两个有序链表序列的合并 (15分) 浙大MOOC数据结构课后作业
题目见02-线性结构1 两个有序链表序列的合并 (15分)
还会有好多错误:
首先要动态分配一个内存,这次不能用L1或者L2的头节点,因为最后要把他们置为空。
带有头节点的链表,头节点不存储信息,指向链表第一个节点(带有Data的)。

List Merge( List L1, List L2 ){
    List Lr,L;
    L = (List)malloc(sizeof(struct Node));
    Lr = L;  //把这个头节点记录下来
    //使用p q代替L1L2,因为后面我们需要把L1L2置为空
    List p = L1 -> Next;
    List q = L2 -> Next;

    while(p&&q){
        if(p->Data >= q->Data){
            //L->Data = q->Data;不需要改Data直接改指针就行
            L->Next = q;
            q = q->Next;
            L = L->Next;
        }
        else if(p->Data < q->Data){
            //L->Data = p->Data;
            L->Next = p;
            p = p->Next;
            L = L->Next;
        }
    }
    if(p){
        L->Next = p; //错写成L = p;
    }
    else if(q){
        L->Next = q;
    }

//这里使用方法1的 L -> Next = p?p:q;比较简洁
    L1 -> Next = NULL;
    L2 -> Next = NULL;
    return Lr;  
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值