链表和顺序表习题(二)

1.判断单链表是否带环?若带环,求环的长度?求环的入口点?

  用快慢指针。快指针每走两步,慢指针走一步,如果两者在某个点处相遇,则链表带环。快指针每次走两步,而慢指针每次走一步是有原因的:若快指针每次走3或者更多,而慢指针每次走一,可能会有快慢指针错过,得不到想要的相遇点。(图中k为大于一正整数,表示快指针走过整个环的次数)
这里写图片描述
  相遇点得到后,再用两个相同速度指针,P1从链表头开始每次走1,P2从相遇点开始每次走1,当二者重合时,即为环入口点。

2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)

  两个链表若是相交,则必然有一个交点,在交点之后具有共同节点。
这里写图片描述
  判断是否相交,以及找出交点可以用如下方法:

  1. 计算两个链表的长度
  2. 判断尾节点是否相同,若相同,则相交
  3. 长链表先走长出短链表的长度个节点,然后遍历两个链表,找出第一个公共节点,也就是交点

3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)

  这个问题大致可以分为如下几种情况(图中蓝色线条表示链表结构):
这里写图片描述

  1. 判断两个链表是否带环,若其中一个带环,另一个不带环,则必然不相交,若两个都不带环,按照问题2处理,否则看下面的步骤
  2. 剩下的情况就是4、5、6三种,此时,判断两个链表环入口点是否一致,若一致,则如情况5相交,按照问题二中的步骤处理交点,若不一致,则看步骤三
  3. 情况4、6,找出链表1的入环点,遍历链表2,如果链表2中有链表1的入环节点,则证明相交,否则如情况6.

4.复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。

  方法如下:

  1. 复制每个节点(节点内的 date )并在源节点之后尾插
  2. 整个链表如图中所示,复制节点指针
  3. 拆分链表
    这里写图片描述
    ListNode NewList(ListNode pHead) {  
    if (pHead == NULL) {  
        return NULL;  
    }  
    //复制并且插入  
    ListNode p = pHead;  
    while (p != NULL) {  
        ListNode tmp = new ListNode(p.label);  
        tmp.next = p.next;  
        p.next = tmp;  

        p = tmp.next;  
    }  
    //复制节点指针  
    p = pHead;  
    while (p != NULL) {  
        if (p.random != NULL) {  
            p.next.random = p.random.next;  
        }  
        p = p.next.next;  
    }  
    //拆分链表  

    ListNode head = pHead.next;  
    ListNode q = head;  
    p = pHead;  

    while (q.next != NULL) {  
        p.next = q.next;  
        p = p.next;  

        q.next = p.next;  
        q = q.next;  
    }  
    p.next = NULL;  //最后将原来链表的尾部设置为null  
    return head;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值