文章目录


简介

单链表对应着单向循环链表,即原来单链表最后一个结点指向本来为空,现在指向头结点;双向链表对应着双向循环链表,即原来双向链表最后一个结点的后驱结点为空,现在指向头结点,原来双向链表的头结点是没有前驱结点的,现在双向循环链表的头结点的前驱结点指向双向循环链表的尾结点

Java 实现

逻辑思路

逻辑上双向循环链表只不过是在双向链表上多加了循环这个条件,我们在初始化时候使头结点前驱和后驱都指向自己,其他操作和双向链表都差不多

算法图解

数据结构-双向循环链表_算法

代码实现

// 结点
class Node {
int data;
Node prior = null;
Node next = null
}

// 双向循环链表
public class DoublyLinkedCircularList {
// 头结点
Node head;

// 初始化
public DoublyLinkedCircularList() {
head = new Node();
head.prior = head;
head.next = head;
}

// 前插法创建双向循环链表(倒序)
public void createFromHead(int[] arr) {
for (int i = 0; i < arr.length; i++) {
Node node = new Node();
node.data = arr[i];
node.next = head.next;
node.prior = head;
node.next.prior = node;
head.next = node;
}
}

// 尾插法创建双向循环链表(正序)
public void createFromTail(int[] arr) {
Node h = head;
for (int i = 0; i < arr.length; i++) {
Node node = new Node();
node.data = arr[i];
node.next = head;
node.prior = h;
node.next.prior = node;
h.next = node;
h = node;
}
}

// 添加
public void add(Node n) {
Node h;
for (h = head; h.next != head; h = h.next);
n.next = head;
n.prior = h;
n.next.prior = n;
h.next = n;
}

// 查询
public int search(int num) {
int k = 0;
for (Node h = head; h.next != head; k++,h = h.next);
if (num < 1 || num > k)
throw new Exception("数字超过范围!");
Node h = head;
for (int i = 1; i <= num; i++,h = h.next);
return h.data;
}

// 插入
public void insert(int num, Node n) {
int k = 0;
for (Node h = head; h.next != head; k++,h = h.next);
if (num < 1 || num > k)
throw new Exception("数字超过范围!");
Node h = head;
for (int i = 1; i < num; i++,h = h.next);
n.next = h.next;
n.prior = h;
n.next.prior = n;
h.next = n;
}

// 删除
public int delete(int num) {
int k = 0;
for (Node h = head; h.next != head; k++,h = h.next);
if (num < 1 || num > k)
throw new Exception("数字超过范围!");
Node h = head;
for (int i = 1; i < num; i++,h = h.next);
int e = h.next.data;
h.next.next.prior = h;
h.next = h.next.next;
return e;
}

// 获取双向链表头结点
public Node getHead() {
return head;
}

// 双向循环链表的拼接
public void spliceDoublyLinkedCircularList(DoublyLinkedCircularList dlcl) {
dlcl.getHead().prior.next = head;
dlcl.getHead().prior = head.prior;
head.prior.next = dlcl.getHead();
head.prior = dlcl.getHead().prior;
}
}