Java数据结构之双端链表原理与实现方法

Java数据结构之双端链表原理与实现方法

一、什么是双端链表?

双端链表是一种链式数据结构,它每个节点都有两个指针:一个指向前一个节点,一个指向后一个节点。它具有链表的所有特点,而且还有一些独特的优点:对于一个双向链表,我们可以从头到尾遍历,也可以从尾到头遍历。在某些情况下,它比单向链表更有用,因为它可以执行逆序遍历。

二、双端链表的原理

双端链表由节点构成,每个节点包含两个引用/指针,一个指向前一个节点,指针称为"prev",一个指向后一个节点,指针称为"next"。如下图所示:

+------+    +------+    +------+
| data |    | data |    | data |
+------+    +------+    +------+
| prev |<-->| prev |<-->| prev |
+------+    +------+    +------+
| next |--> | next |--> | next |
+------+    +------+    +------+

双端链表有两个特殊节点:头节点和尾节点。头节点是链表的第一个节点,尾节点是链表的最后一个节点。头节点的"prev"指针指向"null",尾节点的"next"指针指向"null"。

三、双端链表的实现

3.1 双端链表节点的类定义

为了实现双端链表,我们需要定义一个节点类:

class Node<E> {
    E data;
    Node<E> prev;
    Node<E> next;

    public Node(E data, Node<E> prev, Node<E> next) {
        this.data = data;
        this.prev = prev;
        this.next = next;
    }
}

在这个节点类中,我们定义了一个泛型类型的数据成员"data"和两个引用类型的"prev"和"next",分别指向前一个节点和后一个节点。并实现了一个构造函数,用于创建一个新节点。

3.2 双端链表的类定义

双端链表的类定义如下:

public class DoubleLinkedList<E> {
    private Node<E> head;
    private Node<E> tail;
    private int size;

    public DoubleLinkedList() {
        head = null;
        tail = null;
        size = 0;
    }

    //添加新节点到链表尾部
    public void add(E element) {
        Node<E> newNode = new Node<E>(element, tail, null);
        if (tail != null) {
            tail.next = newNode;
        }
        tail = newNode;
        if (head == null) {
            head = newNode;
        }
        size++;
    }

    //获取指定下标的节点
    public Node<E> getNode(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        Node<E> ptr = head;
        for (int i = 0; i < index; i++) {
            ptr = ptr.next;
        }
        return ptr;
    }

    //获取指定下标的节点的值
    public E get(int index) {
        return getNode(index).data;
    }

    //在指定节点后插入节点
    public void addAfter(Node<E> node, E element) {
        Node<E> newNode = new Node<E>(element, node, node.next);
        node.next = newNode;
        if (node == tail) {
            tail = newNode;
        } else {
            newNode.next.prev = newNode;
        }
        size++;
    }

    //在指定节点前插入节点
    public void addBefore(Node<E> node, E element) {
        Node<E> newNode = new Node<E>(element, node.prev, node);
        node.prev = newNode;
        if (node == head) {
            head = newNode;
        } else {
            newNode.prev.next = newNode;
        }
        size++;
    }

    //移除指定节点
    public void remove(Node<E> node) {
        if (node == head) {
            head = node.next;
        } else {
            node.prev.next = node.next;
        }
        if (node == tail) {
            tail = node.prev;
        } else {
            node.next.prev = node.prev;
        }
        size--;
    }
}

在这个双端链表类中,我们定义了三个数据成员:

  • "head" – 链表的第一个节点的引用。如果链表为空,则为"null"。
  • "tail" – 链表的最后一个节点的引用。如果链表为空,则为"null"。
  • "size" – 链表中节点的数量。

我们实现了五个公共方法:

  • "add" – 在链表的末尾添加一个新节点。
  • "getNode" – 获取给定索引处的节点。该方法用于支持其他方法的实现。
  • "get" – 获取给定索引处节点的值。
  • "addAfter" – 在给定节点的后面添加新节点。
  • "addBefore" – 在给定节点的前面添加新节点。
  • "remove" – 从链表中移除给定的节点。

以上这些方法以及节点类的定义可以满足双端链表的基本操作。

3.3 双端链表的使用示例

public class DoubleLinkedListTest {
    public static void main(String[] args) {
        DoubleLinkedList<String> list = new DoubleLinkedList<>();
        list.add("Java");
        list.add("Python");
        list.add("C++");

        Node<String> secondNode = list.getNode(1);
        list.addAfter(secondNode, "PHP");
        list.addBefore(secondNode, "JavaScript");

        Node<String> thirdNode = list.getNode(2);
        list.remove(thirdNode);

        System.out.println("Size of List : " + list.size);
        System.out.println("Head of List : " + list.head.data);
        System.out.println("Tail of List : " + list.tail.data);
        for (int i = 0; i < list.size; i++) {
            System.out.println("Data at Index " + i + " : " + list.get(i));
        }
    }
}

在这个示例中,我们向双端链表中插入三个元素("Java", "Python", "C++")。然后,在第二个元素后面添加"PHP",在第二个元素前面添加"JavaScript"。最后,从链表中删除第三个元素("C++")。最后打印链表的大小、头元素,尾元素和所有元素。

输出结果如下:

Size of List : 3
Head of List : JavaScript
Tail of List : Python
Data at Index 0 : JavaScript
Data at Index 1 : Java
Data at Index 2 : PHP

四、总结

双端链表是一种链式数据结构,具有许多链表的优点,它之所以称为"双向",是因为每个节点都有两个指针指向前一个节点和后一个节点。这使得它能够执行双向遍历。实现双端链表需要定义一个节点类以及一个双端链表类,同时实现一些基本操作如"添加"、"获取"、"插入"和"删除"等。以上内容是双端链表的基本原理和实现方法的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java数据结构之双端链表原理与实现方法 - Python技术站

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

相关文章

  • C++高级数据结构之二叉查找树

    C++高级数据结构之二叉查找树 什么是二叉查找树 二叉查找树,也称二叉搜索树(BST,Binary Search Tree),是一种常见的基于二叉树的数据结构,主要用于快速查找与排序。在二叉查找树上,左子树的每个节点都比其根节点小,右子树的每个节点都比其根节点大,同时整棵树也满足二叉树的性质。 二叉查找树的实现 我们可以通过C++语言实现二叉查找树的基本操作…

    数据结构 2023年5月17日
    00
  • Java concurrency集合之LinkedBlockingDeque_动力节点Java学院整理

    Java Concurrency集合之LinkedBlockingDeque_动力节点Java学院整理 LinkedBlockingDeque是什么? LinkedBlockingDeque是java.util.concurrent包下一个双向阻塞队列,用于在多线程的环境中处理元素序列,它支持在队列两端添加和移除元素。LinkedBlockingDeque可…

    数据结构 2023年5月17日
    00
  • C语言数据结构之 折半查找实例详解

    C语言数据结构之 折半查找实例详解 什么是折半查找? 折半查找是一种在有序数组中查找某个特定元素的算法。其基本思想是将查找的值与数组的中间元素比较,如果比中间元素小,则在数组的左半部分查找;如果比中间元素大,则在数组的右半部分查找,直到找到该元素或查找范围为空。 折半查找算法的流程 确定要查找的数组arr和其元素个数n,以及要查找的元素value。 设定左边…

    数据结构 2023年5月17日
    00
  • 数据结构 – 绪论

    01.绪论 1. 概念 1.1 数据结构 数据 Data:信息的载体。能被计算机识别并处理的符号的集合。 数据元素 Data element:数据的基本单位,通常作为一个整体进行考虑和处理。一个数据元素往往由若干数据项组成。数据项是组成数据元素的不可分割的最小单位。 如学生的信息记录就是一个数据元素,它由学号、姓名、性别等组成。 数据对象 Data obje…

    算法与数据结构 2023年4月18日
    00
  • 「双端队列BFS」电路维修

    本题为3月23日23上半学期集训每日一题中B题的题解 题面 题目描述 Ha’nyu是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上。Rika的家里有一辆飞行车。有一天飞行车的电路板突然出现了故障,导致无法启动。 电路板的整体结构是一个R行C列的网格( \(R,C \leq 500\) ),如右图所示。每个格点都是…

    算法与数据结构 2023年4月18日
    00
  • 关于图片存储格式的整理(BMP格式介绍)

    关于图片存储格式的整理(BMP格式介绍) 一、BMP格式概述 BMP全称为Bitmap,是一种基础的图像保存格式,它的格式十分简单,就是将每个像素点的颜色信息直接保存在文件中,因此它的信息量相对较大。 BMP格式的文件头有标准结构,其中包含位图的宽、高、颜色数、位图大小等信息,其中颜色数的位数(色深)决定了BMP文件的大小。BMP文件还可以包含调色板,来进行…

    数据结构 2023年5月17日
    00
  • C语言编程数据结构线性表之顺序表和链表原理分析

    C语言编程数据结构线性表之顺序表和链表原理分析 线性表的定义 线性表是由n(n>=0)个数据元素a1、a2、…、an组成的有限序列,通常用(a1, a2, …, an)表示,其中a1是线性表的第一个元素,an是线性表的最后一个元素。线性表中的元素个数n称为线性表的长度,当n=0时,线性表为空表。 线性表的分类 根据存储结构,线性表可以分为顺序表…

    数据结构 2023年5月17日
    00
  • C++深入浅出探索数据结构的原理

    标题:C++深入浅出探索数据结构的原理攻略 介绍 《C++深入浅出探索数据结构的原理》是一本深入讲解C++数据结构的书籍。在本攻略中,我们将介绍该书的主要内容和要点,以及学习该书的步骤和建议。 内容 该书分为三个部分,分别是数据结构的基础、线性表和树。 数据结构的基础 第一部分主要讲解数据结构的基础知识,包括算法分析、时间复杂度和空间复杂度等。这一部分对于初…

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