java数据结构之实现双向链表的示例

yizhihongxing

Java数据结构之实现双向链表的示例

1. 什么是双向链表?

双向链表,英文名为doubly linked list,是一种链表结构。与单向链表不同,双向链表中的每一个节点除了保存了指向下一个节点的指针外,还保存了指向前一个节点的指针。因此,双向链表可双向遍历,可以从前向后或从后向前遍历。

2. 双向链表的实现

2.1 节点类的实现

创建节点类Node,并定义节点的属性和方法。

public class Node<E> {
    private E data; // 数据
    private Node<E> prev; // 前一个节点
    private Node<E> next; // 后一个节点

    // 构造方法
    public Node(E data, Node<E> prev, Node<E> next) {
        this.data = data;
        this.prev = prev;
        this.next = next;
    }

    // setter和getter方法
    public void setData(E data) {
        this.data = data;
    }

    public E getData() {
        return data;
    }

    public void setPrev(Node<E> prev) {
        this.prev = prev;
    }

    public Node<E> getPrev() {
        return prev;
    }

    public void setNext(Node<E> next) {
        this.next = next;
    }

    public Node<E> getNext() {
        return next;
    }
}

在构造方法中初始化节点的属性,setData()和getData()方法用于设置和获取节点的数据,setPrev()和getPrev()方法用于设置和获取前一个节点,setNext()和getNext()方法用于设置和获取后一个节点。

2.2 双向链表类的实现

创建双向链表类DoublyLinkedList,并定义双向链表的属性和方法。

public class DoublyLinkedList<E> {
    private Node<E> head; // 头节点
    private Node<E> tail; // 尾节点
    private int size = 0; // 链表长度

    // 构造方法
    public DoublyLinkedList() {
        head = null;
        tail = null;
    }

    // 获取链表长度
    public int size() {
        return size;
    }

    // 判断链表是否为空
    public boolean isEmpty() {
        return size == 0;
    }

    // 向链表尾部添加节点
    public void add(E data) {
        addLast(data);
    }

    // 向链表尾部添加节点
    public void addLast(E data) {
        Node<E> newNode = new Node<E>(data, tail, null);
        if (tail == null) { // 链表为空时,新节点既是头节点又是尾节点
            head = newNode;
            tail = newNode;
        } else {
            tail.setNext(newNode);
            tail = newNode;
        }
        size++;
    }

    // 向链表头部添加节点
    public void addFirst(E data) {
        Node<E> newNode = new Node<E>(data, null, head);
        if (head == null) { // 链表为空时,新节点既是头节点又是尾节点
            head = newNode;
            tail = newNode;
        } else {
            head.setPrev(newNode);
            head = newNode;
        }
        size++;
    }

    // 获取链表中指定位置的节点
    public Node<E> getNode(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        Node<E> node = head;
        for (int i = 0; i < index; i++) {
            node = node.getNext();
        }
        return node;
    }

    // 获取链表中指定位置节点的数据
    public E get(int index) {
        return getNode(index).getData();
    }

    // 修改链表中指定位置节点的数据
    public void set(int index, E data) {
        Node<E> node = getNode(index);
        node.setData(data);
    }

    // 在链表中指定位置插入节点
    public void add(int index, E data) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        if (index == 0) {
            addFirst(data);
        } else if (index == size) {
            addLast(data);
        } else {
            Node<E> oldNode = getNode(index);
            Node<E> newNode = new Node<E>(data, oldNode.getPrev(), oldNode);
            oldNode.getPrev().setNext(newNode);
            oldNode.setPrev(newNode);
            size++;
        }
    }

    // 删除链表中指定位置节点
    public void remove(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        if (index == 0) {
            head = head.getNext();
            if (head != null) {
                head.setPrev(null);
            } else {
                tail = null;
            }
        } else if (index == size - 1) {
            tail = tail.getPrev();
            if (tail != null) {
                tail.setNext(null);
            } else {
                head = null;
            }
        } else {
            Node<E> oldNode = getNode(index);
            oldNode.getPrev().setNext(oldNode.getNext());
            oldNode.getNext().setPrev(oldNode.getPrev());
            oldNode.setData(null);
        }
        size--;
    }
}

在构造方法中初始化链表的头节点和尾节点,size()方法用于获取链表长度,isEmpty()方法用于判断链表是否为空。add()、addLast()、addFirst()方法用于向链表中添加节点,getNode()方法用于获取链表中指定位置的节点,get()方法用于获取链表中指定位置节点的数据,set()方法用于修改链表中指定位置节点的数据,add()方法用于在链表中指定位置插入节点,remove()方法用于删除链表中指定位置节点。

3. 示例说明

3.1 示例一:创建双向链表并向其中添加数据

public static void main(String[] args) {
    DoublyLinkedList<String> list = new DoublyLinkedList<String>();
    list.addLast("A");
    list.addLast("B");
    list.addFirst("C");
    list.add(1, "D");
    System.out.println(list.get(0)); // output: C
    System.out.println(list.get(1)); // output: D
    System.out.println(list.get(2)); // output: A
    System.out.println(list.get(3)); // output: B
}

首先创建一个DoublyLinkedList对象list,并向其中添加数据。addLast()方法将"A"和"B"分别添加到链表尾部,addFirst()方法将"C"添加到链表头部,add()方法将"D"插入到链表中间位置。最后输出链表中各个位置的数据。

3.2 示例二:在双向链表中删除节点

public static void main(String[] args) {
    DoublyLinkedList<String> list = new DoublyLinkedList<String>();
    list.addLast("A");
    list.addLast("B");
    list.addFirst("C");
    list.add(1, "D");
    System.out.println(list.get(2)); // output: A
    System.out.println(list.size()); // output: 4
    list.remove(2);
    System.out.println(list.get(2)); // output: D
    System.out.println(list.get(3)); // output: B
    System.out.println(list.size()); // output: 3
}

首先创建一个DoublyLinkedList对象list,并向其中添加数据。addLast()方法将"A"和"B"分别添加到链表尾部,addFirst()方法将"C"添加到链表头部,add()方法将"D"插入到链表中间位置。然后删除链表中第2个位置的数据,最后输出链表中各个位置的数据和链表长度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java数据结构之实现双向链表的示例 - Python技术站

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

相关文章

  • MySQL索引原理详解

    MySQL索引原理详解 MySQL索引是一种数据结构,用于帮助查询语句更快地访问到所需的数据,提高数据库查询效率。本文将详细讲解MySQL索引的原理、类型及如何创建索引。 索引原理 B树 MySQL索引底层数据结构主要采用B树,B树是一种多路平衡查找树。B树的每一个节点可以存储多个键值,每个节点的子节点个数也可以大于2,从而使得查询效率更高。 索引分类 My…

    数据结构 2023年5月17日
    00
  • C语言链表案例学习之通讯录的实现

    让我详细讲解一下“C语言链表案例学习之通讯录的实现”的完整攻略。 1. 案例简介 本案例的目的是通过实现一个简单的通讯录程序,来学习C语言链表的原理和操作。程序主要功能涵盖通讯录添加、删除、修改以及查询。 2. 程序架构 程序的整体结构如下所示: 头文件声明 结构体定义 函数声明 主函数 函数实现 其中,头文件声明包含stdio.h、stdlib.h以及st…

    数据结构 2023年5月17日
    00
  • C语言进阶数据的存储机制完整版

    C语言进阶数据的存储机制完整版攻略 1. 前言 C语言是一门高度可控的语言,其中其数据的存储机制是必须掌握的基础知识点。本文介绍了C语言数据存储的机制,包括变量在内存中的分配、指针的应用及结构体的组织等内容,旨在帮助读者掌握C语言中的数据存储机制。 2. 变量在内存中的分配 变量在内存中的分配既涉及到内存的分配可操作性,也涉及到相应的存储结构。 2.1. 变…

    数据结构 2023年5月17日
    00
  • qqwry.dat的数据结构图文解释第1/2页

    “qqwry.dat的数据结构图文解释第1/2页”的完整攻略 1. 什么是qqwry.dat? qqwry.dat是一个IP地址库,包含了全球的IP地址信息,例如:所属国家、所属地区、详细地址等信息。在大多数系统或应用程序中,都可以使用qqwry.dat来查询IP地址信息。 2. qqwry.dat的数据结构 qqwry.dat的数据结构可以通过两个文件来描…

    数据结构 2023年5月16日
    00
  • Java数据结构之单链表的实现与面试题汇总

    Java数据结构之单链表的实现与面试题汇总 一、前言 单链表是数据结构中最基础的数据结构之一,也是在面试时经常会考察的一个知识点。本文将详细介绍单链表的实现过程,并对常见的单链表面试题进行总结,帮助大家深入了解单链表的原理和应用。 二、单链表的实现 单链表是由一些列节点构成的,每个节点包括一个数据和一个指向下一个节点的指针。下面我们将实现一个简单的单链表,并…

    数据结构 2023年5月17日
    00
  • C语言数据结构与算法之链表(一)

    欢迎阅读本篇文章,本文将为大家详细讲解C语言中数据结构与算法之链表。接下来,将从以下几个方面为大家讲述: 链表的定义 链表的特点 链表的分类 单向链表的实现及应用 双向链表的实现及应用 示例说明 1. 链表的定义 链表是由一系列节点组合而成的数据结构,每个节点都包含了一个数据域和一个指向下一个节点的指针域。其中,链表的头结点为第一个节点,而尾节点为最后一个节…

    数据结构 2023年5月17日
    00
  • 设要采用CRC编码传送的数据信息x=1001,当生成多项式为G(x)=1101时,请写出它的循环校验码。若接收方收到的数据信息x’ =1101,说明如何定位错误并纠正错误

    题目:设要采用CRC编码传送的数据信息x=1001,当生成多项式为G(x)=1101时,请写出它的循环校验码。若接收方收到的数据信息x’ =1101,说明如何定位错误并纠正错误 根据题目描述,需要采用CRC编码对数据信息x=1001进行编码,生成多项式为G(x)=1101。下面是计算循环冗余校验码的步骤:1.首先将数据信息x乘以x的次数,使得它的位数与G(x…

    算法与数据结构 2023年4月18日
    00
  • C语言中关于树和二叉树的相关概念

    C语言中关于树和二叉树的相关概念 树的概念 在计算机科学中,树是一种非常常见的数据结构,它由一组节点(通常称为元素)和一组连接节点的边组成。树是一种无向的、连通的、无环的图形结构,其中有一个节点被称为根节点,它没有父节点,而其他节点都有一个父节点。 树的定义很抽象,但在程序设计中,我们通常会使用一个节点类来实现树结构。一个节点类通常包含两个元素:一个是表示当…

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