`
brandNewUser
  • 浏览: 455817 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

单向链表的闭环判断

 
阅读更多

单向链表,只能访问next元素,如何判断是否存在环?

 

最简单的方案,不考虑空间复杂度,我们会想到使用一个Set来保存集合,用来记录已经访问过的元素

/**
     * 最简单的算法,但需要的空间比较高,一个Set集合
     * @param link
     * @param <T>
     * @return
     */
    public static <T>  boolean containsCircle1(Link<T> link) {
        if(link == null){
            return false;
        }
        T value = link.getValue();
        Set<T> values = new HashSet<T>();
        values.add(value);
        while ((link = link.getNext()) != null){
            if(link == null){
                return false;
            }
            value = link.getValue();
            if (values.contains(value)) {
                return true;
            }
        }
        return false;
    }

 

 

这会浪费O(n)的空间,效率低下,如果链表长度过长,占用的空间会非常大,考虑一下有无其他简便的方法?

 

使用两个指针,分别以不同的速度向前遍历,一个以单个元素为步长,另一个以两个元素为步长,如果两个元素步长的指针追上了后面的指针,这便证明该链表中存在环。这样,只需要额外的两个空间,空间复杂度为O(1)

 

/**
     * 使用两个指针,一个以速度1前进,另一个以速度2前进,如果存在闭环,则必定会出现交叉碰面
     * @param link
     * @param <T>
     * @return
     */
    public static <T> boolean containsCircle2(Link<T> link) {
        if (link == null || link.getNext() == null) {
            return false;
        }
        Link<T> first = link;
        Link<T> second = link.getNext();
        while (second != null && second.getNext() != null && second.getNext().getNext() != null) {
            first = first.getNext();
            second = second.getNext().getNext();
            if (first.getValue() == second.getValue()) {
                return true;
            }
        }
        return false;
    }

 

 

 

分享到:
评论

相关推荐

    数据结构:单向循环链表源码

    3. **插入和删除操作**:插入和删除节点的操作与普通单向链表类似,但需要考虑链表是否为空及插入位置的判断。 **单向循环链表常见操作** 1. **创建链表**:初始化链表,通常创建一个节点作为链表的首节点。 2. **...

    利用单向循环链表存储结构模拟约瑟夫问题,按照出列的顺序印出每个人的编号。

    循环链表没有头节点,最后一个节点的指针会指向第一个节点,形成一个闭环。这使得在环中遍历变得简单,适合模拟约瑟夫问题的循环特性。 在【概要设计】部分,我们看到问题被划分为三个模块:主程序模块、类单元模块...

    循环链表 数据结构

    相较于普通链表,循环链表在末尾节点指向头节点,形成一个闭环,这一特性使其在某些操作上更为便捷,如遍历整个链表、实现循环队列等。 ### 循环链表的数据结构 循环链表由一系列节点组成,每个节点包含两部分:...

    约瑟夫环单循环链表C语言实现

    单向循环链表是一种特殊的线性表存储结构,其中每个节点包含一个指向下一个节点的指针,最后一个节点的指针指向链表的头节点,形成一个闭环。在约瑟夫环问题中,单向循环链表非常适合模拟游戏参与者围成一圈的情形。...

    C语言链表相关面试题.zip

    链表的种类主要有单向链表、双向链表和循环链表。单向链表中的节点只包含一个指向下一个节点的指针;双向链表中的节点包含两个指针,一个指向前一个节点,另一个指向下一个节点;循环链表则是首尾相接的链表,形成一...

    Python实现的单向循环链表功能示例

    与普通的单向链表不同,单向循环链表中的最后一个节点不是指向`None`,而是指向链表的第一个节点(即头节点),形成一个闭环。 ### 原理介绍 在单向循环链表中,每个节点包含两部分:数据域(用于存储实际数据)和...

    数据结构中链表及常见操作.docx

    单向链表是最简单的链表形式,它由多个节点组成,每个节点包含两部分:数据域和指针域。数据域用于存储实际数据,而指针域则用于存储指向下一个节点的地址。这种结构只能从前向后遍历。 在单向链表中,节点的结构...

    【课件】2.3.4_循环链表.pdf

    而循环链表则需要通过其他方式判断遍历是否完成,如设置一个标志位或记录遍历过的节点数量等。 3. **插入和删除操作**:虽然循环链表与普通链表的插入和删除操作基本类似,但在处理循环特性时需要额外注意更新尾结点...

    [详细完整版]链表数据结构.pdf

    - 特点:除了单向链表的下一个节点指针外,每个节点还包含一个指向前一个节点的指针。 - 访问方式:可以在链表中双向移动,既可以从头部向尾部遍历,也可以从尾部向头部遍历。 - 应用场景:适合于需要频繁进行...

    约瑟夫环代码,建立一个具有n个链结点的循环链表。

    单向循环链表是一种特殊的数据结构,每个节点包含一个指向下一个节点的指针,最后一个节点的指针指向头节点,形成闭环。 #### 三、代码解析 1. **数据结构定义**: ```c typedef struct node { int num; // ...

    实战应用Java算法分析与设计(链表、二叉树、哈夫曼树、图、动态规划)视频

    链表根据结构不同分为单向链表、双向链表和循环链表等。 **2. 单向链表操作** - **创建链表**: 初始化一个头结点,然后通过节点插入操作来构建链表。 - **节点插入**: 在指定位置插入新节点。 - **节点删除**: 删除...

    C语言进阶-第五讲 数据结构与链表

    单向链表是最简单的链表形式,其中每个节点包含一个数据部分和一个指向下一个节点的指针。 #### 双向链表 双向链表中的每个节点除了包含指向下一个节点的指针外,还有一个指向前一个节点的指针。这使得双向链表...

    CDoubleNodeTreate.rar

    这与单向链表不同,单向链表的节点只有一个指针,只指向下一个节点。双向链表的这种特性使得在链表中的前后移动更加灵活,但同时也增加了存储空间的需求。 1. **创建双向链表**:创建双向链表通常从一个空的头节点...

    Linux内核中链表和散列表的实现原理揭秘

    - **单向非循环**:与双向循环链表不同,散列表中的链表是单向的,不构成闭环。 - **双指针**:每个节点除了`next`指针外,还有一个指向其前驱节点的指针的指针(`pprev`),这有助于快速地进行节点的插入和删除操作。...

    linked list problems

    链表主要分为单向链表、双向链表和循环链表三种类型: 1. **单向链表**:每个节点仅有一个指针指向下一个节点。 2. **双向链表**:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点,便于双向遍历。 ...

    数据结构约瑟夫环实验报告

    2. **单向循环链表**:一种特殊的链表结构,每个节点包含一个指向下一个节点的指针,最后一个节点的指针指向头节点,形成闭环,适合处理环形队列或循环问题。 #### 二、实验设计与实现 **实验目的**:通过实践加深...

    数据结构笔试面试汇总.doc

    **解题思路**:根据题目要求,我们需要设计一个算法来判断单向链表是否包含环,并且该算法需要满足内存使用量是固定的,不会随着链表长度的变化而变化。常见的解决方案有两种:快慢指针法和哈希表法。但由于题目要求...

    数据结构约瑟夫环

    与普通链表不同的是,最后一个节点的指针不是指向`NULL`,而是指向链表的第一个节点,形成一个闭环。 **主要特点:** - **循环性:**最后一个节点指向第一个节点。 - **单向性:**每个节点只包含指向下一个节点的...

Global site tag (gtag.js) - Google Analytics