概念:将单链表终端节点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种首尾相接的单链表称为单循环链表,简称循环链表;
循环链表和单链表的区别:尾结点的指针不指向null,而是指向head头结点。
/*
* 循环链表
* 将单链表终端节点的指针由空指针改为指向头结点,
* 就使整个单链表形成一个环,这种首尾相接的单链表称为单循环链表,简称循环链表
*/
public class MyCircularLinkedList {
public static void main(String[] args) {
CircularLinkedList<String> list2 = new CircularLinkedList<String>();
list2.addHead("aaa");
list2.add("bbb");
list2.addByIndex(2, "ccc");
System.out.println(list2.getElement(5));
System.out.println(list2.toString());
System.out.println(list2.length());
System.out.println(list2.setElement(2, "ddd"));
System.out.println(list2.toString());
System.out.println(list2.remove(1));
System.out.println(list2.toString());
System.out.println(list2.removeAll());
System.out.println(list2.toString());
}
}
class CircularNode<T> {
private T data;// 将循环链表设置为私有的,外界只能通过get和set进行访问
private CircularNode next;
// 构造方法
CircularNode(T data, CircularNode next) {
this.data = data;
this.next = next;
}
// 调用重载的构造方法
CircularNode(T data) {
this(data, null);
}
CircularNode() {
this(null, null);
}
// 提供get和set方法
public T getData() {
return this.data;
}
public CircularNode getNext() {
return this.next;
}
public void setData(T data) {
this.data = data;
}
public void setNext(CircularNode next) {
this.next = next;
}
// 重写toString方法
public String toString() {
return getData().toString();
}
}
class CircularLinkedList<T> {
public CircularNode<T> head, tail;// 头和尾
CircularLinkedList() {
this(null);// 调用重载的构造方法
}
// 建表 如果参数为空则建空表;若参数不为空,则建一张有头有尾的结点,尾结点的指针指向头结点
CircularLinkedList(T data) {
if (data == null) {
head = new CircularNode<T>(data, null);// 创建头结点,数据为data 指针为空
tail = head;// 尾结点和头结点相同
tail.setNext(head);// 尾结点的指针域指向头结点,使首尾形成环
} else {
head = new CircularNode<T>();
tail = new CircularNode<T>(data, head);
head.setNext(tail);// 等价于 head.next = tail;
}
}
// 清空链表 头=尾 this=null
public void clear() {
removeAll();
head.setNext(tail);
tail.setNext(head);
head = tail;
}
// 删除循环表中所有的数据元素
public boolean removeAll() {
// 将指针都释放 便于垃圾回收
if (isEmpty())
return false;
CircularNode<T> tempNext = head.getNext();
while (tempNext != head) {
tempNext = tempNext.getNext();
head.setNext(tempNext);
}
return true;
}
// 如果头=尾 返回true;否则返回false;
public boolean isEmpty() {
return tail == head;
}
// 获取链表当前元素的个数
public int length() {
int len = 0;
CircularNode<T> temp = head;
while (temp.getNext() != head) {
len++;
temp = temp.getNext();
}
return len;
}
// 获取index处的数据元素
public T getElement(int index) {
if (index < 0)
return null;
CircularNode<T> temp = head;
int j = 0;
while (j < index && temp.getNext() != head) {
j++;
temp = temp.getNext();
}
// 如果 index大于链表的长度 则返回最后一个元素的data
return temp.getData();
}
// 将参数链表添加到当前链表的后面
public boolean add(CircularLinkedList<T> list) {
tail.setNext(list.head.getNext());
list.tail.setNext(head);
list.head.setNext(null);
list.head = null;
return true;
}
// 尾添
public boolean add(T element) {
if (element == null)
return false;
if (isEmpty()) {
noElement(element);
} else {
CircularNode<T> temp = new CircularNode<T>(element, head);// 创建一个结点
tail.setNext(temp);// 指向头结点head
tail = temp;
}
return true;
}
// 若循环表中没有元素
public void noElement(T element) {
CircularNode<T> temp = new CircularNode<T>(element, head);
head.setNext(temp);
tail = temp;
}
// 头添
public boolean addHead(T element) {
if (element == null)
return false;
if (isEmpty()) {
noElement(element);
} else {
CircularNode<T> temp = new CircularNode<T>(element, head.getNext());// 指针指向指定添加元素的下一个元素
head.setNext(temp);
}
return true;
}
// 任意位置添加
public boolean addByIndex(int index, T element) {
if (element == null)
return false;
if (index <= 0)
addHead(element);
else if (index >= length()) {
add(element);
} else if (index > 0 && index < length()) {
int j = 0;
CircularNode<T> temp = head;
CircularNode<T> tempNext = temp.getNext();
while (j < index && tempNext != head) {
j++;
temp = tempNext;
tempNext = tempNext.getNext();
}
CircularNode<T> node = new CircularNode<T>(element, tempNext);
temp.setNext(node);
}
return true;
}
// 删除头元素
public T removeHead() {
if (isEmpty())
return null;
CircularNode<T> temp = head.getNext();
head.setNext(temp.getNext());
return temp.getData();
}
// 删除任意位置的元素
public T remove(int index) {
if (isEmpty())
return null;
T element = null;
if (index <= 0)
removeHead();
if (index > length())
index = length();
if (index > 0) {
int j = 1;
CircularNode<T> temp = head;
CircularNode<T> tempNext = head.getNext();
while (j < index && tempNext != head) {
temp = tempNext;
tempNext = tempNext.getNext();
j++;
}
element = tempNext.getData();
temp.setNext(tempNext.getNext());
}
return element;
}
// 删除表中的第一条element数据
public T remove(T element) {
T data = null;
if (isEmpty())
return null;
if (element == null)
return null;
CircularNode<T> temp = head;
CircularNode<T> tempNext = head.getNext();
while (!(tempNext.getData().equals(element))
&& tempNext.getNext() != head) {
temp = tempNext;
tempNext = tempNext.getNext();
}
data = tempNext.getData();
temp.setNext(tempNext.getNext());
return data;
}
// 修改任意位置上的元素,并将其原值返回
public T setElement(int index, T element) {
if (isEmpty())
return null;
if (element == null)
return null;
if (index <= 0)// 若索引值小于等于0 则 修改第一个位置
index = 1;
if (index > length())// 若索引值大于 index 修改最后一个元素
index = length();
CircularNode<T> temp = head.getNext();
T data = null;
int j = 1;
while (j < index) {
j++;
temp = temp.getNext();
}
data = temp.getData();
temp.setData(element);
return data;
}
// 重写父类toString方法
@Override
public String toString() {
if (isEmpty())
return "[ ]";
StringBuffer sb = new StringBuffer();
sb.append("[ ");
int L = length();
for (int i = 1; i <= L; i++) {
sb.append(getElement(i) + " ");
}
sb.append("]");
return sb.toString();
}
}