【数据结构】链表面试题升级版

1、复杂链表的复制

复杂链表
一个链表的每个结点,有一个next指针指向下一个结点,还有一个random指针指向这个链表中的随机一个结点或者NULL。
现在要求复制这个链表,并返回复制后的新链表。
思路如下:
在这里插入图片描述
复杂链表的数据类型:

typedef struct ComplexNode
{
    int data;
    ComplexNode *next;
    ComplexNode *random;
}ComplexNode;

代码如下:

//创建一个新结点
ComplexNode *CreateComNode(int data)
{
    ComplexNode *newNode = (ComplexNode *)malloc(sizeof(ComplexNode));
    newNode->data = data;
    newNode->next = NULL;
    newNode->random = NULL;
    return newNode;
}
ComplexNode *CopyComplexList(ComplexNode **pFirst)
{
    ComplexNode *newNode = NULL;
    ComplexNode *cur = NULL;
    //1.复制每个结点,让新结点跟在老结点后面
    cur = *pFirst;
    while(cur != NULL)
    {
        newNode = CreateComNode(cur->data);
        newNode->next = cur->next;
        cur->next = newNode;
        cur = newNode->next;
    }
    //2、复制random
    cur = *pFirst;
    while(cur != NULL)
    {
        newNode = cur->next;
        if(cur->random != NULL)
        {
            newNode->random = cur->random->next;
        }
        cur = newNode->next;
    }
    //3、把一个链表拆成两个链表
    ComplexNode *newNext = NULL;
    ComplexNode *next = NULL;
    ComplexNode *result = NULL;
    int flag = 1;
    cur = *pFirst;
    while(cur != NULL)
    {
        newNode = cur->next;
        if(flag)
        {
            result = newNode;
            flag = 0;
        }
        next = newNode->next;
        if(next == NULL)
        {
            newNext = NULL;
        } 
        else
        {
            newNext = next->next;
        }
        cur->next = next;
        newNode->next = newNext;
        cur = next;
    }
    return result;
}
2、判断两个链表是否相交,若相交,求交点(假设链表不带环)

思路如下:
在这里插入图片描述
代码如下:

//计算链表长度
int GetListLen(ListNode *p)
{
    int count = 0;
    ListNode *cur = p;
    while(cur != NULL)
    {
       count++;
       cur = cur->next;
    }
    return count;
}
//判断两条链表是否相交,若相交,返回交点
ListNode *IsIntersect(ListNode *p1, ListNode *p2)
{
     ListNode *cur1 = p1;
     ListNode *cur2 = p2;
     int len1 = 0;
     int len2 = 0;
     int ret = 0;
     while(cur1 != NULL)
     {
         cur1 = cur1->next;
     }
     while(cur2 = cur2->next)
     {
         cur2 = cur2->next;
     }
     if(cur1 == cur2)//如果条件成立,说明相交
     {
         cur1 = p1;
         cur2 = p2;
         len1 = GetListLen(p1);
         len2 = GetListLen(p2);
        if(len1>len2)
        {
           ret = len1-len2;
           while(ret--)
           {
                cur1 = cur1->next;
           }
        }
        else if(len1<len2)
        {
           ret = len2-len1;
           while(ret--)
           {
                cur2 = cur2->next;
           }
        }
        while(cur1 != cur2)
        {
            cur1 = cur1->next;
            cur2 = cur2->next;
        }
        return cur1; //找到交点
     }
     else
         return NULL;
}
3、判断单链表是否带环?若带环,求环的长度?求环的入口点?

思路如下:
在这里插入图片描述代码如下:

//判断是否带环,带环返回快慢指针相遇结点
ListNode *IsCircleList(ListNode *p)
{
    int count = 0;
    ListNode *fast = p;
    ListNode *slow = p;
    while(fast != NULL)
    {
        fast = fast->next;
        count++;
        if(count%2==0)
        {
            slow = slow->next;
        }
        if(fast == NULL)
        {
            break;
        }
        if(fast == slow)
        {
            return fast;
        }
    }
    return NULL;
}
//求环的长度
int LenOfCircle(ListNode *p)
{
    int count = 0;
    ListNode *cur = NULL;
    ListNode *NodeInCircle = NULL;
    //从头遍历链表,找到相遇点
    NodeInCircle = IsCircleList(p);
    cur = p;
    while(cur != NodeInCircle)
    {
        cur = cur->next;
    }
    while(cur->next != NodeInCircle)
    {
        cur = cur->next;
        count++;
    }
    count++;
    return count;
}
//求环的入口点
ListNode *EntryNode(ListNode *p)
{
    ListNode *dot = NULL;
    ListNode *ret = NULL;
    ListNode *cur = NULL;
    ListNode *NodeInCircle = NULL;
    //从头遍历链表,找到相遇点
    NodeInCircle = IsCircleList(p);
    cur = p;
    //找出相遇点的前一个结点,将它置为空指针,相当于从相遇点断开环
    //然后以两条链表相交的角度找入口点,两条链表相交处就是环的入口点
    while(cur->next != NodeInCircle)
    {
        cur = cur->next;
    }
    dot = cur;
    cur->next = NULL;
    cur = NodeInCircle;
    ret = p;
    while(cur != ret)
    {
        cur = cur->next;
        ret = ret->next;
    }
    dot->next = NodeInCircle;
    return cur;
}
4、判断两个链表是否相交,若相交,求交点(假设链表带环)【升级版】

思路如下:
在这里插入图片描述

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值