数据结构:双向链表实践教程

本文详细介绍了如何用Java实现一个基本的双向链表,包括节点定义、链表操作(如添加、删除和遍历),以及双向链表相对于单向链表的优势和适用场景。
摘要由CSDN通过智能技术生成

双向链表是一种更复杂的链表结构,与单向链表类似,但是每个节点除了有一个指向下一个节点的指针外,还有一个指向前一个节点的指针。这种双向链接使得在列表中向前和向后遍历变得更加方便。

下面是如何使用Java实现一个基本的双向链表的步骤:

定义双向链表节点

首先,定义双向链表的节点类,每个节点都有一个值,一个指向前一个节点的指针(prev),和一个指向下一个节点的指针(next)。

public class DoublyListNode {
    int data;
    DoublyListNode prev;
    DoublyListNode next;

    public DoublyListNode(int data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

实现双向链表

接着,我们可以创建一个双向链表类来管理这些节点:

public class DoublyLinkedList {
    private DoublyListNode head;
    private DoublyListNode tail;

    public DoublyLinkedList() {
        head = null;
        tail = null;
    }

    // 在链表头部添加节点
    public void prepend(int data) {
        DoublyListNode newNode = new DoublyListNode(data);
        if (head == null) {
            head = newNode;
            tail = newNode;
        } else {
            head.prev = newNode;
            newNode.next = head;
            head = newNode;
        }
    }

    // 在链表尾部添加节点
    public void append(int data) {
        DoublyListNode newNode = new DoublyListNode(data);
        if (tail == null) {
            head = newNode;
            tail = newNode;
        } else {
            tail.next = newNode;
            newNode.prev = tail;
            tail = newNode;
        }
    }

    // 删除链表中具有特定值的节点
    public void delete(int data) {
        if (head == null) return;

        if (head.data == data) {
            head = head.next;
            if (head != null) {
                head.prev = null;
            } else {
                tail = null;
            }
            return;
        }

        DoublyListNode current = head;
        while (current != null && current.data != data) {
            current = current.next;
        }

        if (current == null) return;

        if (current.next != null) {
            current.next.prev = current.prev;
        } else {
            tail = current.prev;
        }

        if (current.prev != null) {
            current.prev.next = current.next;
        }
    }

    // 打印链表从头到尾
    public void printForward() {
        DoublyListNode current = head;
        while (current != null) {
            System.out.print(current.data + " <-> ");
            current = current.next;
        }
        System.out.println("null");
    }

    // 打印链表从尾到头
    public void printBackward() {
        DoublyListNode current = tail;
        while (current != null) {
            System.out.print(current.data + " <-> ");
            current = current.prev;
        }
        System.out.println("null");
    }
}

使用双向链表

现在我们可以创建一个双向链表实例,在链表中添加和删除节点,并打印链表:

public class Main {
    public static void main(String[] args) {
        DoublyLinkedList list = new DoublyLinkedList();

        // 在链表头部添加数据
        list.prepend(3);
        list.prepend(2);
        list.prepend(1);

        // 在链表尾部添加数据
        list.append(4);
        list.append(5);

        // 打印链表(正向)
        list.printForward(); // 输出: 1 <-> 2 <-> 3 <-> 4 <-> 5 <-> null

        // 打印链表(反向)
        list.printBackward(); // 输出: 5 <-> 4 <-> 3 <-> 2 <-> 1 <-> null

        // 删除链表中的一个节点
        list.delete(3);

        // 再次打印链表
        list.printForward(); // 输出: 1 <-> 2 <-> 4 <-> 5 <-> null
    }
}

在这个示例中,我们定义了双向链表节点DoublyListNode,它具有一个整数数据字段,一个指向前一个节点的指针prev和一个指向下一个节点的指针nextDoublyLinkedList类管理一个双向链表,包括在头部和尾部添加节点,以及删除具有特定值的节点的操作。

总结

双向链表相比单向链表,由于每个节点都有两个指针,增加了一些内存开销,但也提供了向前和向后遍历的便利性。这种数据结构适用于需要频繁进行双向遍历或在列表中间进行插入和删除操作的场景。掌握双向链表的实现和操作是理解更复杂数据结构和算法的基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值