王道408 数据结构之 给定两个单链表,编写算法找出两个链表的公共节点

基本思想

所谓找出两个单链表的公共节点,就是将链表相交的部分的第一个节点找出来,此节点后的所有节点都是公共节点。
如图,链表A的5个节点分别为a1,a2,c1,c2,c3,链表B的6个节点分别为b1,b2,b3,c1,c2,c3(注意此处没有考虑虚拟头节点的存在)
在这里插入图片描述
显然,从c1开始它们便不可能再出现分支,我们的算法也应当返回c1的地址。

当A、B的长度相同时,找出c1非常简单,只要我们设置两个指针curA, curB同时指向A、B的第一个数据节点,并依次比较两个指针指向的地址值是否相同,最终一定会在c1处返回。
在这里插入图片描述
但是,如果A、B长度不等,就没有这么简单了,curA和curB不会同时经过c1,自然无法在此处判断相等
在这里插入图片描述
解决方法倒是很简单,我们让curA和curB遍历完自己的链表后立刻遍历对方的,这样,就能强行令两个链表长度“相等”,因为在此时两个链表的组成部分分别是 A:蓝色->红色->黄色->红色;B:黄色->红色->蓝色->红色。其中最后一段红色就是公共部分,同一颜色长度相等,可见最后一段红色之前的长度一定时相等的,由此就将情况进行了化简。
在这里插入图片描述

代码实现

基本操作

下面开始用C++实现本算法,首先我们定义一个带头节点的链表,并定义相关操作:

typedef struct linkedList{
   
    int data;
    linkedList* next;
    //构造函数
    linkedList(){
   
        //我们拿头节点的data域存储指向链表末尾的指针
        printf("链表头节点已创建\n");
        data = 0;
        next = 0;
    }
    //析构函数,只要在栈空间创建头节点就无需担心内存泄漏问题
    ~linkedList(){
   
        int i = 0;
        linkedList* p = next;
        while(p!=0){
   
            linkedList* q = p->next;
            free(p);
            p = q;
            ++i;
        }
        printf("删除了%d个节点\n",i);
    }
    /**
    *从当前节点开始输出后续的所有内容
    **/
    void output(){
   
        linkedList* n = this;
        //printf("%d -> ",data);
        while(n->next != 0){
   
            n = n->next;
            printf("%d -> ",n->data);
        }
        printf("null\n");
    }
    /**
    * 尾插法,将另一节点插入此链表末端,时间复杂度O(n),可以优化为O(1)
    **/
    void insert_back(int value){
   
        //假定当前给出的节点是头节点
        linkedList* newNode = this->data==0?this: (linkedList*)this->data;
        //printf("%d", newNode);
        while(newNode->next != 0) newNode = newNode->next;
        newNode->next = (linkedList*)malloc(sizeof(linkedList));
        //记录当前末尾节点的位置
        this->data = (int) newNode->next;
        newNode->next-
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值