Java-链表
1、什么是链表?
2、链表的特点是什么?
3、链表的实现原理?
4、如何自己写出一个链表?
1、什么是链表?
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。
每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址)。
链表的理解示意图
2、链表的特点是什么?
获取数据麻烦,需要遍历查找,比数组慢
方便插入、删除
3、链表的实现原理
创建一个节点类,其中节点类包含两个部分,第一个是数据域(你到时候要往节点里面储存的信息),第二个是引用域(相当于指针,单向链表有一个指针,指向下一个节点;双向链表有两个指针,分别指向下一个和上一个节点)
创建一个链表类,其中链表类包含三个属性:头结点、尾节点和大小,方法包含添加、删除、插入等等方法。
单向链表的节点类:
1 public class Node {
2 public Object data;
3 public Node next;
4
5 public Node(Object e){
6 this.data = e;
7 }
8 }
双向链表的节点类:
1 public class Node {
2 public Object e;
3 public Node next;
4 public Node pre;
5 public Node(){
6
7 }
8 public Node(Object e){
9 this.e = e;
10 next = null;
11 pre = null;
12 }
13 }
4、如何自己写出一个链表?
代码如下(以双向链表为例,有详细的注释,单向链表同理):
首先创建了一个节点类
1 package MutuLink;
2
3 public class Node {
4 public Object e;
5 public Node next;
6 public Node pre;
7 public Node(){
8
9 }
10 public Node(Object e){
11 this.e = e;
12 next = null;
13 pre = null;
14 }
15 }
然后创建了一个链表类
1 package MutuLink;
2
3 public class MyList {
4 private Node head;
5 private Node tail;
6 private int size = 0;
7
8 public MyList() {
9 head = new Node();
10 tail = new Node();
11 head.next =null;
12 tail.pre = null;
13 }
14
15 public boolean empty() {
16 if (head.next == null)
17 return true;
18 return false;
19 }
20 //找到所找下标节点的前一个节点
21 public Node findpre(int index){
22 Node rnode = head;
23 int dex = -1;
24 while(rnode.next != null){
25 //找到了插入节点的上一个节点
26 if( dex== index - 1){
27 return rnode;
28 }
29 rnode = rnode.next;
30 dex++;
31 }
32 return null;
33 }
34 public Node findthis(int index){
35 Node rnode = head;
36 //把rnode想象为指针,dex为指向的下标,这个地方很容易错,因为当指向最后一个节点时没有判断IF就跳出循环了
37 int dex = -1;
38 while(rnode.next != null){
39 if(dex == index)
40 return rnode;
41 rnode = rnode.next;
42 dex++;
43 }
44 if(dex == size - 1){
45 return rnode;
46 }
47 // Node test = new Node(new Students("haha",1,2));
48 return null;
49 }
50
51 // 往链表末尾加入节点
52 public void add(Object e) {
53 Node node = new Node(e);
54 Node rnode = head;
55 //如果是空链表的话插入一个节点,这个节点的pre不能指向上一个节点,必须指空
56 if (this.empty()) {
57 rnode.next = node;
58 rnode.next.pre = null;
59 tail.pre = node;
60 size++;
61 } else {
62 while (rnode.next != null)
63 rnode = rnode.next;
64 rnode.next = node;
65 node.pre = rnode;
66 tail.pre = node;
67 size++;
68 }
69 }
70 //往链表的某一个标插入一个节点
71 public boolean add(int index,Object e){
72 if(index <0||index>=size)
73 return false;
74 Node node = new Node(e);
75 Node prenode = this.findpre(index);
76 node.next = prenode.next;
77 prenode.next.pre = node;
78 prenode.next = node;
79 node.pre = prenode;
80 size++;
81 return true;
82 }
83 public boolean add(int index,MyList myl){
84 if(index <0 || index >= size)
85 return false;
86 Node prenode = this.findpre(index);
87 // myl.tail.pre.next = prenode.next;
88 // prenode.pre = myl.tail.pre;
89 // tail.pre = null;
90 // prenode.next = myl.head.next;
91 // myl.head.next.pre = prenode;
92 // head.next = null;
93 myl.tail.pre.next = prenode.next;
94 prenode.next.pre = myl.tail.pre.pre;
95 myl.head.next.pre = prenode.pre;
96 prenode.next = myl.head.next;
97 myl.head = null;
98 myl.tail = null;
99 size+=myl.size;
100 return true;
101 }
102
103 public Object remove(int index){
104 Object ob= this.get(index);
105 if(index <0 || index >= size)
106 return null;
107 //特殊情况,当移除节点是最后一个节点的时候
108 //较为复杂通过画图来写代码
109 if(index == size - 1){
110 Node prenode = this.findpre(index);
111 this.tail.pre = this.tail.pre.pre;
112 this.tail.pre.next.pre = null;
113 this.tail.pre.next =null;
114 size--;
115 return ob;
116 }
117 //比较复杂,通过画图解决
118 else{
119 Node prenode = this.findpre(index);
120 prenode.next = prenode.next.next;
121 prenode.next.pre.next = null;
122 prenode.next.pre = prenode.next.pre.pre;
123 size--;
124 return ob;
125 }
126 }
127
128
129 public Object get(int index){
130 Node thisnode = this.findthis(index);
131 return thisnode.e;
132 }
133 public int size(){
134 return size;
135 }
136 }
最后测试
1 package MutuLink;
2
3 import java.util.Random;
4
5 public class manage {
6 public static void main(String[] args) {
7 String name = "";
8 int credit;
9 int age;
10 int size;
11 MyList myl = new MyList();
12 Random random = new Random();
13 size = random.nextInt(5) + 1;
14 for (int i = 0; i < size; i++) {
15 credit = random.nextInt(5);
16 age = random.nextInt(5) + 18;
17 for (int j = 0; j < 4; j++) {
18 name += (char) (random.nextInt(26) + 97);
19 }
20 Students stu = new Students(name, credit, age);
21 myl.add(stu);
22 name = "";
23 }
24
25 System.out.println("Size of myl1 is "+ myl.size());
26 for(int i = 0; i < myl.size() ;i++){
27 Students stu2 = (Students) myl.get(i);
28 stu2.show();
29 }
30 // //测试能否在链表末尾加入节点(成功)
31 // for(int i = 0; i < myl.size() ;i++){
32 // Students stu2 = (Students) myl.get(i);
33 // stu2.show();
34 // }
35 // //测试能否通过下标加入一个节点(成功)
36 // Students stu3 = new Students("cyt",5,18);
37 // myl.add(1, stu3);
38 // System.out.println("Size is "+ myl.size());
39 // for(int i = 0; i < myl.size() ;i++){
40 // Students stu2 = (Students) myl.get(i);
41 // stu2.show();
42 // }
43
44 MyList myl2 = new MyList();
45 size = random.nextInt(5) + 1;
46 for (int i = 0; i < size; i++) {
47 credit = random.nextInt(5);
48 age = random.nextInt(5) + 18;
49 for (int j = 0; j < 4; j++) {
50 name += (char) (random.nextInt(26) + 97);
51 }
52 Students stu2 = new Students(name, credit, age);
53 myl2.add(stu2);
54 name = "";
55 }
56 System.out.println("Size is of myl2 "+ myl2.size());
57 for(int i = 0; i < myl2.size() ;i++){
58 Students stu2 = (Students) myl2.get(i);
59 stu2.show();
60 }
61
62
63
64 myl.add(1, myl2);
65 System.out.println("Size is of myl1 "+ myl.size());
66 for(int i = 0; i < myl.size() ;i++){
67 Students stu2 = (Students) myl.get(i);
68 stu2.show();
69 }
70
71
72 }
73
74 }
结果输出: