数据结构-双向循环链表实践

双向循环链表是链表的一种,它的每个节点都有两个指针:一个指向下一个节点,另一个指向前一个节点。与单向循环链表类似,双向循环链表中的最后一个节点指向第一个节点,而第一个节点也指向最后一个节点,从而形成一个闭环。这种结构使得在链表中向前和向后遍历变得非常容易。

下面是如何在Java中实现双向循环链表的步骤:

定义双向循环链表节点

首先,我们需要定义链表节点类,它包含数据部分以及指向前一个和后一个节点的指针。

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

    public DoublyCircularListNode(int data) {
        this.data = data;
    }
}

实现双向循环链表

接下来,创建一个双向循环链表类,实现基本的操作方法,如添加节点、删除节点和打印链表。

public class DoublyCircularLinkedList {
    private DoublyCircularListNode head;
    private DoublyCircularListNode tail;

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

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

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

        DoublyCircularListNode current = head;
        do {
            if (current.data == data) {
                if (current == head && current == tail) {
                    // 只有一个节点的情况
                    head = null;
                    tail = null;
                } else if (current == head) {
                    // 删除头节点
                    head = head.next;
                    head.prev = tail;
                    tail.next = head;
                } else if (current == tail) {
                    // 删除尾节点
                    tail = tail.prev;
                    tail.next = head;
                    head.prev = tail;
                } else {
                    // 删除中间节点
                    current.prev.next = current.next;
                    current.next.prev = current.prev;
                }
                return;
            }
            current = current.next;
        } while (current != head);
    }

    // 打印链表
    public void printList() {
        if (head == null) return;

        DoublyCircularListNode current = head;
        do {
            System.out.print(current.data + " <-> ");
            current = current.next;
        } while (current != head);
        System.out.println("(head)");
    }
}

使用双向循环链表

创建一个双向循环链表实例,并在链表中添加、删除节点并打印:

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

        // 向双向循环链表添加节点
        list.append(1);
        list.append(2);
        list.append(3);
        list.append(4);

        // 打印双向循环链表
        list.printList(); // 输出: 1 <-> 2 <-> 3 <-> 4 <-> (head)

        // 删除双向循环链表中的节点
        list.delete(3);

        // 再次打印双向循环链表
        list.printList(); // 输出: 1 <-> 2 <-> 4 <-> (head)
    }
}

总结

双向循环链表结合了双向链表和循环链表的优点,允许在两个方向上遍历,同时具有从链表任何一点开始都能遍历整个链表的特性。它为某些特定的场景提供了很大的便利,如实现高级数据结构(比如斐波那契堆)和解决特定问题(比如约瑟夫问题)。与其他类型的链表相比,双向循环链表的实现稍显复杂,但它提供了额外的灵活性和效率。

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员爱学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值