Java 数据结构与算法系列精讲之环形链表

yizhihongxing

Java 数据结构与算法系列精讲之环形链表

概述

在本文中,我们将探讨环形链表的相关概念,以及如何使用Java语言实现环形链表的各种操作。我们将依次介绍以下几个部分:

  • 环形链表的基本概念
  • 环形链表的创建
  • 环形链表的遍历
  • 环形链表的插入、删除、查找等操作
  • 环形链表的示例程序

环形链表的基本概念

链表是一种基本的数据结构,是由一组节点组成的序列,每个节点包含数据和指向下一节点的指针。链表的最后一个节点指向空地址NULL,可以用于表示链表的结束。但在环形链表中,最后一个节点不再指向 NULL,而是指向链表的第一个节点,形成了一个环形。

环形链表的创建

我们可以使用Java语言定义一个环形链表的节点Node,用class实现,包含数据值和指向下一节点的指针,如下所示:

class Node {
    int data;
    Node next;
    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}

然后我们可以定义一个环形链表的类CircularLinkedList,用来存储整个链表的头节点和尾节点,实现各种操作。具体实现如下:

class CircularLinkedList {
    Node head;
    Node tail;
    public CircularLinkedList() {
        head = null;
        tail = null;
    }
}

接下来,我们就可以通过往链表中添加节点的方式来实现链表的创建。在添加节点时,我们需要判断链表是不是空链表,然后逐个遍历找到尾节点,并把新节点添加到尾节点后面构成环形。具体代码实现如下:

public void add(int data) {
    Node newNode = new Node(data);
    if (head == null) {
        head = newNode;
        tail = newNode;
        newNode.next = head;
    } else {
        tail.next = newNode;
        tail = newNode;
        tail.next = head;
    }
}

环形链表的遍历

遍历链表是常见的操作之一,我们需要从头节点开始,依次访问每个节点,直到尾节点为止。在遍历环形链表时,我们需要担心的是陷入死循环,因此我们可以设置一个循环标志来判断是否到达尾节点位置。代码实现如下:

public void traversal() {
    if (head == null) {
        System.out.println("Empty list...");
        return;
    }
    Node current = head;
    boolean flag = false;
    while (!flag) {
        System.out.print(current.data + " ");
        if (current == tail) {
            flag = true;
        }
        current = current.next;
    }
    System.out.println();
}

环形链表的插入、删除、查找等操作

环形链表的插入、删除、查找等操作与普通链表没有太大区别,具体实现如下:

在指定位置插入节点

public void insert(int index, int data) {
    if (index <= 0) {
        add(data);
    } else if (index > size()) {
        System.out.println("Insert failed, out of range...");
        return;
    } else {
        Node newNode = new Node(data);
        Node current = head;
        int count = 0;
        while (count < index - 1) {
            current = current.next;
            count++;
        }
        newNode.next = current.next;
        current.next = newNode;
    }
}

删除指定节点

public void remove(int index) {
    if (head == null) {
        System.out.println("Empty list...");
        return;
    }
    if (index <= 0) {
        head = head.next;
        tail.next = head;
    } else if (index >= size()) {
        System.out.println("Remove failed, out of range...");
        return;
    } else {
        Node current = head;
        int count = 0;
        while (count < index - 1) {
            current = current.next;
            count++;
        }
        current.next = current.next.next;
        if (index == size() - 1) {
            tail = current;
        }
    }
}

按照数据值查找节点

public Node search(int data) {
    if (head == null) {
        System.out.println("Empty list...");
        return null;
    }
    Node current = head;
    boolean flag = false;
    while (current != null) {
        if (current.data == data) {
            flag = true;
            break;
        }
        current = current.next;
        if (current == tail.next) {
            break;
        }
    }
    if (flag) {
        return current;
    } else {
        System.out.println("Node not found...");
        return null;
    }
}

环形链表的示例程序

我们可以使用环形链表来解决环状报数问题。问题描述:n个人围成一圈,从第一个人开始从1报数,报数到第m个人,然后出圈;接着从出圈的下一个人开始继续从1报数,报数到第m个人,再次出圈;重复进行直到所有人出圈为止。具体代码实现如下:

public static void counting(int n, int m) {
    CircularLinkedList list = new CircularLinkedList();
    for (int i = 1; i <= n; i++) {
        list.add(i);
    }
    Node current = list.head;
    while (current.next != current) {
        for (int i = 1; i < m; i++) {
            current = current.next;
        }
        System.out.print(current.data + " ");
        current = current.next;
        list.remove(current, current.data);
    }
    System.out.println("\nThe last one is: " + current.data);
}

以上就是环形链表的完整攻略,通过本文的阅读,您应该已经对环形链表的概念、创建、遍历和各种操作有了一定的了解。希望本文对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 数据结构与算法系列精讲之环形链表 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C语言 数据结构堆排序顺序存储(升序)

    C语言 数据结构堆排序顺序存储(升序)攻略 1. 堆排序概述 堆排序是一种常见的排序算法,通过构建最大堆或最小堆来实现排序。本文介绍的是使用顺序存储方式实现的最大堆排序,也就是升序排序。 2. 最大堆的定义和实现 最大堆指的是堆结构中父节点的值大于子节点的值,根节点的值最大。对于一棵完全二叉树,若父节点的下标为i,则其左子节点的下标为2i+1,右子节点的下标…

    数据结构 2023年5月17日
    00
  • C语言数据结构哈希表详解

    C语言数据结构哈希表详解 什么是哈希表? 哈希表(Hash Table)是一种采用散列函数(hash函数)将数据映射到一个固定长度的数组中,并且以 O(1) 的时间复杂度进行数据插入、查找、删除操作的数据结构。哈希表主要由以下三个组成部分构成:- 数组:用于存储映射到对应下标上的数据。- 散列函数:将数据映射到数组下标上的规则。- 冲突处理方式:当不同的数据…

    数据结构 2023年5月16日
    00
  • Go 数据结构之堆排序示例详解

    Go 数据结构之堆排序示例详解 什么是堆? 堆(Heap)是一种特殊的树形数据结构,它满足下列性质: 堆中每个节点的关键字都不大于(或不小于)其子节点的关键字。 堆中,根节点(顶端)是最小或最大元素。 堆实际上是一个完全二叉树,因此可以用数组实现。对于下标为i的节点,其左子节点为2i,右子节点为2i+1,父节点为i/2。 堆分为最大堆和最小堆。在最大堆中,父…

    数据结构 2023年5月17日
    00
  • Java数据结构之双端链表原理与实现方法

    Java数据结构之双端链表原理与实现方法 一、什么是双端链表? 双端链表是一种链式数据结构,它每个节点都有两个指针:一个指向前一个节点,一个指向后一个节点。它具有链表的所有特点,而且还有一些独特的优点:对于一个双向链表,我们可以从头到尾遍历,也可以从尾到头遍历。在某些情况下,它比单向链表更有用,因为它可以执行逆序遍历。 二、双端链表的原理 双端链表由节点构成…

    数据结构 2023年5月17日
    00
  • python数据结构之二叉树的建立实例

    下面是Python数据结构之二叉树的建立实例的完整攻略。 一、二叉树的概念 二叉树是一种常用的树形结构,它由一组父子关系组成,其中每个节点都最多有两个子节点。通常我们认为,一个二叉树的根节点是唯一的,它没有父节点,而叶子节点则没有子节点。在二叉树中,节点的左子树和右子树可以为空。 二、二叉树的遍历 二叉树的遍历是指访问二叉树中所有节点的操作,它分为三种不同的…

    数据结构 2023年5月17日
    00
  • C++数据结构关于栈迷宫求解示例

    C++数据结构关于栈迷宫求解示例攻略 在本篇攻略中,我们将使用C++数据结构中的栈来解决迷宫问题,具体将通过两个示例来详细讲解该方法。首先介绍一下栈的概念。 栈的概念 栈是一种“后入先出”的数据结构,即最后压入栈中的元素会首先被弹出,而最早压入栈中的元素会最后被弹出。栈的基本操作有入栈(push)、出栈(pop)、判断是否为空以及读取栈顶元素等。 迷宫问题 …

    数据结构 2023年5月17日
    00
  • JavaScript 处理树数据结构的方法示例

    下面是“JavaScript 处理树数据结构的方法示例”的完整攻略。 什么是树数据结构 树形数据结构是一种非常重要的数据结构,常被用于模拟现实中大量的层级结构。例如:文件目录、网站导航等。其是由一个根节点和若干个子节点构成的,每个节点可以有0个或多个子节点。 使用 JavaScript 处理树形数据结构 了解了树形数据结构后,我们可以使用 JavaScrip…

    数据结构 2023年5月17日
    00
  • 数据结构之位图(bitmap)详解

    数据结构之位图(bitmap)详解 什么是位图? 位图,又称为比特图、Bitmap,是一种非常常用的数据结构。它是一种特殊的数组,只能存储0或1,可以用来表示一些二元状态,如二进制码、字符集、颜色等信息。在数据挖掘、工程设计、网络安全等领域都有广泛的应用。 位图的原理 位图的原理是用数据的位来表示某个元素对应的值。如果对应位为1,则代表该元素存在,否则代表该…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部