Java数据结构——循环链表

www.cnblogs.com/ericz2j/p/1…

1、单向循环链表
表中的最后一个节点的指针域指向头结点,整个链表造成一个环。其余的与单链表相同。html

(如下图片均来自网络,侵删)node

插入操做网络


删除操做dom

简单实现ide

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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();
}
}

  

循环单链表模拟击鼓传花游戏this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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(); //开启线程
}
}

  

2、双向循环链表
从双向链表中的任意一个结点开始,均可以很方便地访问它的前驱结点和后继结点。通常咱们都构造双向循环链表。线程

插入操做指针


删除操做code


简单实现cdn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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();
}
}
相关文章
相关标签/搜索