Java实现链表的思想可以参考 LinkedList的源码
下面实现几点关于单向链表的一些操作:
1 public class LinkList{2 private Nodefirst;3 private Nodelast;4 private intsize;5
6 publicLinkList() {7 first = last = null;8 size = 0;9 }10
11
12 private static class Node{13 private Nodenext;14 privateE data;15 public Node(E data,Nodenext) {16 this.data =data;17 this.next =next;18 }19 }20
21 public voidadd(E e) {22 Node l =last;23 Node newNode = new Node(e, null);24 last =newNode;25 if(first == null) {26 first =newNode;27 } else{28 l.next =newNode;29 }30 size++;31 }32
33
34
35 public static voidmain(String[] args) {36 LinkList link = new LinkList();37 //1.添加
38 link.add(1);39 link.add(2);40 link.add(3);41 link.add(4);42
43 System.out.println("节点个数:" +link.size);44
45 //2.遍历
46 Node node1 =link.first;47 for(int i = 0;i
54 //3.查找单链表中的倒数第k个结点
55 int k = 2;56 //倒数第k个,就是正数第link.size-k+1,(因为是单向,只能正着数)
57 int index = link.size-k+1;58 Node node2 =link.first;59
60 if(link.size <= 0) {61 System.out.println("链表为空");62 return;63 }64 if(link.size <= k && link.size > 0) {65 System.out.println(node2.data);66 return;67 }68
69 for(int i = 1;i
73 System.out.println("这个链表中倒数第" + k + "个节点的值为:" +node2.data);74
75 //4.查找单链表中的中间节点(size + 1 / 2,然后遍历吧)76
77 //5.合并两个有序的单链表,合并之后,仍然有序;78 //这里自己的思路是,创建一个新的链表,将这两个有序的链表中的数据,按序放入到 新链表中
79 LinkList link2 = new LinkList();80 LinkList link3 = new LinkList();81 link2.add(0);82 link2.add(2);83 link2.add(3);84 link2.add(2);85 link2.add(7);86 link2.add(7);87
88 Node node3 =link.first;89 Node node4 =link2.first;90
91 //只有链表1和链表2中还有数据可以放入新链表
92 for(;node3 != null || node4 != null;) {93
94 //当链表1和链表2中都有数据可以去比较,
95 if(node3 != null && node4 != null) {96 if(node3.data node4.data) {101 link3.add(node4.data);102 node4 =node4.next;103 } else if(node3.data ==node4.data) {104 link3.add(node3.data);105 link3.add(node4.data);106 node3 =node3.next;107 node4 =node4.next;108 }109 }110
111
112 //若链表1的数据已经比较完了,链表2的还有数据存在,说明链表2这些剩下的数据都比链表1里面大,直接全部放到新链表后面
113 if(node3 == null && node4 != null) {114 link3.add(node4.data);115 node4 =node4.next;116 } else if(node3 != null && node4 == null) {117 link3.add(node3.data);118 node3 =node3.next;119 }120
121 }122 System.out.print("两个有序的单链表合并后:");123 for(int i = 0;i
130 //6.单链表的反转
131 Node node5 =link.first;132
133 Node pre = null;134 Node next = null;135
136 while(node5 != null) {137 next =node5.next;138 node5.next =pre;139 pre =node5;140 node5 =next;141
142 }143
144 while(pre != null) {145 System.out.print(pre.data + " ");146 pre =pre.next;147 }148 }149 }
注:上面的代码写得比较糟糕,也有很多可以封装的地方,等有时间再整理
提比较重要的几点:
1.关于链表中的泛型,用到泛型的地方,
a)创建这个LinkList的时候,
b)创建Node节点的时候,
c)往Node中添加的数据
2.关于单向链表的添加,
a)添加就是添加在链表的末尾,添加之前,肯定要创建一个 Node节点出来,这个Node节点的下一个节点为null
b)先保存原来的last节点,将这个newNode作为新的last节点
c)如果原先列表中不存在节点,则这个newNode就为 first节点
d)将原来的last节点的next指向这个newNode,就完成添加了 ,最后size++
3.关于合并两个有序的单链表,
a)这里自己的思路是,创建一个新的链表,将这两个有序的链表中的数据,按序放入到 新链表中,当然还有别的思路
4.关于单向链表的反转,
a)首先要有一个pre节点和 next 节点,用于保存当前节点的前一个节点和后一个节点
b)
用前面定义的next,保存当前节点的下一个节点
当前节点下一节点重新指向当前节点的前一节点(箭头反向) 1->2->3 1
让pre,当前节点,next,依次向后移动,这样就可以对下一个节点进行反转
c)还有一种递归的方式,递归和直接遍历的区别就是,直接遍历是从前往后按顺序一个一个反转
递归是从后往前,先反转最后一个节点,再回头反转前面
这边给出一个递归的示例:
1 public static voidmain(String[] args) {2 Node head = new Node(0);3 Node node1 = new Node(1);4 Node node2 = new Node(2);5 Node node3 = new Node(3);6 head.setNext(node1);7 node1.setNext(node2);8 node2.setNext(node3);9
10 //打印反转前的链表
11 Node h =head;12 while (null !=h) {13 System.out.print(h.getData() + " ");14 h =h.getNext();15 }16 //调用反转方法
17 head =Reverse1(head);18
19 System.out.println("\n**************************");20 //打印反转后的结果
21 while (null !=head) {22 System.out.print(head.getData() + " ");23 head =head.getNext();24 }25 }26
27 /**
28 * 递归,在反转当前节点之前先反转后续节点29 */
30 public staticNode Reverse1(Node head) {31 //head看作是前一结点,head.getNext()是当前结点,reHead是反转后新链表的头结点
32 if (head == null || head.getNext() == null) {33 return head;//若为空链或者当前结点在尾结点,则直接还回
34 }35 Node reHead = Reverse1(head.getNext());//先反转后续节点head.getNext()
36 head.getNext().setNext(head);//将当前结点的指针域指向前一结点
37 head.setNext(null);//前一结点的指针域令为null;
38 return reHead;//反转后新链表的头结点
39 }40 }41
42 classNode {43 private int Data;//数据域
44 private Node Next;//指针域
45
46 public Node(intData) {47 //super();
48 this.Data =Data;49 }50
51 public intgetData() {52 returnData;53 }54
55 public void setData(intData) {56 this.Data =Data;57 }58
59 publicNode getNext() {60 returnNext;61 }62
63 public voidsetNext(Node Next) {64 this.Next =Next;65 }