Java數據結構——循環鏈表


一、單向循環鏈表
表中的最后一個節點的指針域指向頭結點,整個鏈表形成一個環。其他的與單鏈表相同。

(以下圖片均來自網絡,侵刪)

插入操作


刪除操作

簡單實現

public class CiNode {
private Object data;
private CiNode next;
private static CiNode first; // 臨時結點,頭結點,並不是鏈表里想要的值,起到標記鏈表頭的作用

public CiNode() {
super();
}

public CiNode(Object data, CiNode next) {
super();
this.data = data;
this.next = next;
}

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}

public CiNode getNext() {
return next;
}

public void setNext(CiNode next) {
this.next = next;
}

public static void add(CiNode node, int index) {
if (index == 0) {
node.next = first.next;
first.next = node;
} else {
int temp = 0;
for (CiNode n = first.next;; n = n.next) {
temp++;
if (temp == index) {
node.next = n.next;
n.next = node;
break;
}
}
}
}

public static void remove(int index) {
if (index % 5 == 0) { // 刪除第一個元素,考慮循環
first.next = first.next.next;
} else {
int temp = 0;
for (CiNode n = first.next;; n = n.next) {
if (n == first) {
temp -= 1; // 減一是因為鏈表循環計數時會把first記一次,所以這里減一次,使下標一致
}
temp++;
if (temp == index) {
n.next = n.next.next;
break;
}
}
}
}

public static void display() {
for (CiNode n = first.next; n != first; n = n.next) {
System.out.print(n.data + " ");
}
System.out.println();
}

public static void main(String[] args) {
CiNode node4 = new CiNode("ddd", null);
CiNode node3 = new CiNode("ccc", node4);
CiNode node2 = new CiNode("bbb", node3);
CiNode node1 = new CiNode("aaa", node2);
first = new CiNode(null, node1);
node4.next = first;
System.out.println("當前鏈表:");
display();
add(new CiNode("eee", null), 5); // 傳5進去是為了體現循環,當參數大於了鏈表長度時,又回到first
System.out.println("插入后鏈表:");
display();
remove(11);
System.out.println("刪除后鏈表:");
display();
}
}

  

循環單鏈表模擬擊鼓傳花游戲

public class JiGuChuanHua implements Runnable {
private Object person;//游戲的人的data
private JiGuChuanHua next;//指向下一個人,
private static JiGuChuanHua first;//第一個人

public JiGuChuanHua() {
super();
}
//構造方法
public JiGuChuanHua(Object person, JiGuChuanHua next) {
super();
this.person = person;
this.next = next;
}

@Override
public void run() {
JiGuChuanHua loser = first; //以第一個人為起點
double time = (Math.random() + 0.5) * 10; //隨機產生游戲時間(5-15s)
boolean flag = true;//結束線程的標志
System.out.println("本局游戲時間:" + time + "s");
System.out.println("游戲開始:");
System.out.println(loser.person);//初始游戲時,花在第一個人手上,打印
double startTime = System.currentTimeMillis();//獲取開始游戲的時間
while (flag) {
for (JiGuChuanHua node = first;; node = node.next) {
loser = node.next;//loser指向下一個人,模擬傳花過程
System.out.println(loser.person);//打印拿到花的人
try {
Thread.sleep((long) (Math.random() * 500));//線程睡眠,模擬花在每一個人手中停留時間
} catch (InterruptedException e) {
e.printStackTrace();
}
double endTime = System.currentTimeMillis();//傳完一個人時的時間
if (endTime - startTime >= time * 1000) {//游戲時間到,這里不具備原子性,所以是大於等於
flag = false;//標志位置為false
break;
}
}
}
System.out.println("游戲結束,拿到花的人是:" + loser.person);//打印最后拿到花的人
}

public static void main(String[] args) {
//將參加游戲的人用鏈表連起來,構成一個循環
JiGuChuanHua person5 = new JiGuChuanHua("e", null);
JiGuChuanHua person4 = new JiGuChuanHua("d", person5);
JiGuChuanHua person3 = new JiGuChuanHua("c", person4);
JiGuChuanHua person2 = new JiGuChuanHua("b", person3);
JiGuChuanHua person1 = new JiGuChuanHua("a", person2);
person5.next = person1;
first = person1;
JiGuChuanHua jgch = new JiGuChuanHua();
Thread thread = new Thread(jgch);
thread.start(); //開啟線程
}
}

  

二、雙向循環鏈表
從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅結點和后繼結點。一般我們都構造雙向循環鏈表。

插入操作


刪除操作


簡單實現

public class CiDlNode {
private Object data;
private CiDlNode next;
private CiDlNode prev;
private static CiDlNode first;

public CiDlNode() {
super();
}

public CiDlNode(Object data, CiDlNode next, CiDlNode prev) {
super();
this.data = data;
this.next = next;
this.prev = prev;
}

public static void insert(Object data, int index) {
CiDlNode node = new CiDlNode(data, null, null);
if (index == 0) {
node.next = first.next;
first.next.prev = node;
first.next = node;
node.prev = first;

} else {
int temp = 0;
for (CiDlNode n = first.next;; n = n.next) {
temp++;
if (temp == index) {
node.next = n.next;
node.next = n.next;
n.next.prev = node;
n.next = node;
node.prev = n;
break;
}
}
}
}

public static void remove(Object data) {
for (CiDlNode n = first.next; n != first; n = n.next) {
if (n.data.equals(data)) {
n.prev.next = n.next;
n.next.prev = n;
}
}
}

public static void print() {
for (CiDlNode node = first.next; node != first; node = node.next) {
System.out.print(node.data + " ");
}
System.out.println();
}

public static void main(String[] args) {
first = new CiDlNode("0", null, null);
CiDlNode node1 = new CiDlNode("aaa", null, first);
CiDlNode node2 = new CiDlNode("bbb", null, node1);
CiDlNode node3 = new CiDlNode("ccc", null, node2);
CiDlNode node4 = new CiDlNode("ddd", first, node3);
node3.next = node4;
node2.next = node3;
node1.next = node2;
first.next = node1;
System.out.println("當前鏈表:");
print();
insert("ddd", 5);
System.out.println("插入后鏈表:");
print();
remove("ddd");
System.out.println("刪除后鏈表:");
print();
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM