美文网首页
寻找链表中环的位置

寻找链表中环的位置

作者: lxr_ | 来源:发表于2022-10-01 14:27 被阅读0次

参考https://blog.csdn.net/zwx900102/article/details/122293540
链表结构定义

#include <iostream>
#include <unordered_set>

using namespace std;

typedef struct ListNode
{
    int data;
    ListNode* next;
}*List;

链表的尾插法和遍历函数实现

//尾插法 
void InsertTail(List& L, int data)
{
    ListNode* p = L;                    //头结点
    ListNode* n = new ListNode;
    n->data = data;
    n->next = NULL;

    if (p->next != NULL)
    {
        while (p->next)
        {
            p = p->next;
        }
    }
    p->next = n;
}
//遍历
void TraverseList(List L)
{
    ListNode* p = L->next;
    while (p)
    {
        cout << p->data << " ";
        p = p->next;
    }
    cout << endl;
}

使用哈希表判断链表是否有环,并找到环的入口点

bool IsCycle_hash(List L)
{
    unordered_set<ListNode*> h;

    ListNode* p = L->next;
    while (p)
    {

        if (h.find(p) != h.end())           //如果再哈希表中找到了当前结点
        {
            cout << "入口点:" << p->data << endl;
            return true;
        }

        h.insert(p);
        p = p->next;
    }
    return false;
}

使用快慢指针判断链表是否有环并寻找环的位置

bool IsCycle(List L)
{
    ListNode* slow = L;         //慢指针
    ListNode* fast = L->next->next;         //快指针

    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;

        if (slow == fast)
        {
            return true;
        }
    }
    return false;
}

//查找环的入口位置
int FindCycle(List L)
{
    ListNode* slow = L;                         //慢指针
    ListNode* fast = L;                         //快指针

    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;

        if (slow == fast)                       //快慢指针相遇则证明有环
        {
            slow = L;                           //慢指针重新指向链表头指针
            while (slow != fast)                //从相遇点和头指针一起后移,再次相遇的点则为入口点
            {
                slow = slow->next;
                fast = fast->next;
            }
            return slow->data;
        }
    }

    return 0;                                   //未找到环
}

main函数

int main(int argc, char** argv)
{
    List l = new ListNode;      //头结点
    l->next = NULL;

    InsertTail(l, 1);
    InsertTail(l, 2);
    InsertTail(l, 3);
    InsertTail(l, 4);
    InsertTail(l, 5);

    TraverseList(l);

    //构成一个环
    ListNode* p = l;
    while (p->next)
    {
        p = p->next;                    //找到最后一个结点
    }
    p->next = l->next->next;            //最后一个结点的next域指向第二个结点,构成一个环
    //p->next = p;                      //最后一个结点的next域指向自身,构成一个环

    cout << "入口点:" << p->next->data << endl;
    cout << "是否有环:" << IsCycle(l) << endl;
    cout << "入口点:" << FindCycle(l) << endl;

    cout << "*********************使用hash_set求解**************" << endl;
    cout << "是否有环:" << IsCycle_hash(l) << endl;

    return 0;
}

相关文章

  • 寻找链表中环的位置

    参考https://blog.csdn.net/zwx900102/article/details/1222935...

  • 寻找链表中环的起始位置

    解法如下:定义两个指针:p1和p2,当p2按照每次2步,p1每次一步的方式走,发现p2和p1重合,确定了单向链表有...

  • 关于链表经典算法题都在这里了

    1.单链表反转(LeetCode 206) 2.链表中环的检测 (LeetCode 141) 3.求链表中环开始结...

  • 链表

    1判断一个单链表是否有环 2判断一个单链表中环的入口 3在链表的第k个位置插入一个结点 4找到链表中的倒数第k个位...

  • 链表——链表中环的检测

  • 链表--链表中环的检测

    给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索...

  • 常见算法总结

    链表 单链表反转链表中环的检测两个有序的链表合并删除链表倒数第 n 个结点求链表中间第n个节点

  • 链表

    链表 单链表反转链表中环的检测两个有序链表合并删除链表倒数第n个节点求链表的元素总个数 一.单向链表 链表共有特征...

  • 链表中环检测

  • 链表中环的检测

    1. 怎么检测一个单向链表中是否有环 同样借助于快慢指针,思路如下: 定义 fast、slow 两个指针同时指向链...

网友评论

      本文标题:寻找链表中环的位置

      本文链接:https://www.haomeiwen.com/subject/waddartx.html