寻找链表入环的第一个节点

采用快慢指针的方法:
快指针fast走两步,慢指针slow走一步,如果相遇就是带环链表;
然后让cur1从链表头开始走,cur2从相遇点开始走,再次相遇的位置就是入环的第一点

public class DateCycle {
    static class ListNode {
        int val;
       ListNode next;

        public ListNode(int val) {
            this.val = val;
        }
        //使用快慢指针
        public ListNode dateCtCycle(ListNode head){
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&slow!=null){
            fast=fast.next.next;//快指针一次走两步,慢指针一次走一步,如果带环,则会相遇
            slow=slow.next;
            if(fast==slow){
                //相遇就跳出循环
                break;
            }
        }
            if (fast == null||slow==null){
                //说明不带换
                return null;
            }
            //创建两个节点,一个从链表头部出发,一个从相遇位置出发,再次相遇的位置就是入环第一节点
            ListNode cur1=head;
            ListNode cur2=fast;
            cur1=cur1.next;
            cur2=cur2.next;
            while(cur1!=cur2){
                cur1=cur1.next;
                cur2=cur2.next;
            }
            return cur1;
        }
    }
}

在删除带头结点的双向链表的第i个节点时,首先要明白带头结点的链表的结构。带头结点的双向链表有一个特殊节点,即头结点,它不存储有效数据,但链接了链表第一个和最后一个元素。第i个节点是指从头结点开始计数的第i个节点,即不包括头结点本身。 删除第i个节点的一般步骤如下: 1. 检查i的有效性:确保i的值在链表的范围内(1 <= i <= 链表长度)。 2. 寻找第i个节点:从头结点出发,遍历链表直到找到第i个节点。由于带头结点,实际上我们需要找到第i+1个节点。 3. 调整指针: - 如果第i个节点存在,调整其前驱节点和后继节点的指针,使它们跳过第i个节点,直接相连。 - 如果第i个节点第一个有效节点(即i=1),需要调整头结点的指针指向第二个节点。 4. 删除节点:释放第i个节点所占用的内存空间。 5. 更新链表长度:如果需要的话,更新链表中元素的数量。 这是一个简单的代码框架,展示删除操作的逻辑: ```c typedef struct Node { int data; struct Node* prev; struct Node* next; } Node; void deleteNodeAtPosition(Node* head, int position) { if (position < 1 || head == NULL) return; // 检查i的有效性 Node* current = head; for (int i = 0; i < position && current != NULL; ++i) { current = current->next; } if (current == NULL) return; // 如果没有找到第i个节点,则返回 Node* prevNode = current->prev; Node* nextNode = current->next; if (prevNode != NULL) { prevNode->next = nextNode; // 前驱节点指向后继节点 } else { // 如果要删除的是第一个有效节点,则需要更新头结点 head = nextNode; } if (nextNode != NULL) { nextNode->prev = prevNode; // 后继节点指向前驱节点 } free(current); // 释放内存 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值