01.import java.util.HashMap;
02.import java.util.Scanner;
03.import java.util.Stack;
04.
05./**
06. *
07. * @author kerryfish
08. * 关于java中链表的操作
09. * 1. 求单链表中结点的个数: getListLength
10. * 2. 将单链表反转: reverseList(遍历),reverseListRec(递归)
11. * 3. 查找单链表中的倒数第K个结点(k > 0): reGetKthNode
12. * 4. 查找单链表的中间结点: getMiddleNode
13. * 5. 从尾到头打印单链表: reversePrintListStack,reversePrintListRec(递归)
14. * 6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList, mergeSortedListRec
15. * 7. 对单链表进行排序,listSort(归并),insertionSortList(插入)
16. * 8. 判断一个单链表中是否有环: hasCycle
17. * 9. 判断两个单链表是否相交: isIntersect
18. * 10. 已知一个单链表中存在环,求进入环中的第一个节点: getFirstNodeInCycle, getFirstNodeInCycleHashMap
19. * 11. 给出一单链表头指针head和一节点指针delete,O(1)时间复杂度删除节点delete: deleteNode
20. */
21.public class LinkedListSummary {
22. /**
23. * @param args
24. *
25. */
26. public static class Node{
27. int value;
28. Node next;
29. public Node(int n){
30. this.value=n;
31. this.next=null;
32. }
33. }
34. public static void main(String[] args) {
35. // TODO Auto-generated method stub
36. Scanner in=new Scanner(System.in);
37. Node head=null;
38. if(in.hasNextInt()){
39. head=new Node(in.nextInt());
40. }
41. Node temp=head;
42. while(in.hasNextInt()){
43. temp.next=new Node(in.nextInt());
44. temp=temp.next;
45. }
46. in.close();
47. //int len=getListLength(head);
48. //Node reHead=reverseList(head);
49. //reHead=reverseListRec(reHead);
50. //Node node_k=reGetKthNode(head,3);
51. //Node mid=getMiddleNode(head);
52. //reversePrintListRec(head);
53. //reversePrintListStack(head);
54. //Node mergeHead=mergeSortedList(head,null);
55. //Node sortHead=listSort(head);
56.
57. }
58. //求单链表中结点的个数: getListLength
59. public static int getListLength(Node head){
60. int len=0;
61. while(head!=null){
62. len++;
63. head=head.next;
64. }
65. return len;
66. }
67. //将单链表反转,循环
68. public static Node reverseList(Node head){
69. if(head==null||head.next==null)return head;
70. Node pre=null;
71. Node nex=null;
72. while(head!=null){
73. nex=head.next;
74. head.next=pre;
75. pre=head;
76. head=nex;
77. }
78. return pre;
79. }
80. //将单链表反转,递归
81. public static Node reverseListRec(Node head){
82. if(head==null||head.next==null)return head;
83. Node reHead=reverseListRec(head.next);
84. head.next.next=head;
85. head.next=null;
86. return reHead;
87. }
88. //查找单链表中的倒数第K个结点(k > 0)
89. public static Node reGetKthNode(Node head,int k){
90. if(head==null)return head;
91. int len=getListLength(head);
92. if(k>len)return null;
93. Node target=head;
94. Node nexk=head;
95. for(int i=0;i<k;i++){
96. nexk=nexk.next;
97. }
98. while(nexk!=null){
99. target=target.next;
100. nexk=nexk.next;
101. }
102. return target;
103. }
104. //查找单链表的中间结点
105. public static Node getMiddleNode(Node head){
106. if(head==null||head.next==null)return head;
107. Node target=head;
108. Node temp=head;
109. while(temp!=null&&temp.next!=null){
110. target=target.next;
111. temp=temp.next.next;
112. }
113. return target;
114. }
115. //从尾到头打印单链表,递归
116. public static void reversePrintListRec(Node head){
117. if(head==null)return;
118. else{
119. reversePrintListRec(head.next);
120. System.out.println(head.value);
121. }
122. }
123. //从尾到头打印单链表,栈
124. public static void reversePrintListStack(Node head){
125. Stack<Node> s=new Stack<Node>();
126. while(head!=null){
127. s.push(head);
128. head=head.next;
129. }
130. while(!s.isEmpty()){
131. System.out.println(s.pop().value);
132. }
133. }
134. //合并两个有序的单链表head1和head2,循环
135. public static Node mergeSortedList(Node head1,Node head2){
136. if(head1==null)return head2;
137. if(head2==null)return head1;
138. Node target=null;
139. if(head1.value>head2.value){
140. target=head2;
141. head2=head2.next;
142. }
143. else{
144. target=head1;
145. head1=head1.next;
146. }
147. target.next=null;
148. Node mergeHead=target;
149. while(head1!=null && head2!=null){
150. if(head1.value>head2.value){
151. target.next=head2;
152. head2=head2.next;
153. }
154. else{
155. target.next=head1;
156. head1=head1.next;
157. }
158. target=target.next;
159. target.next=null;
160. }
161. if(head1==null)target.next=head2;
162. else target.next=head1;
163. return mergeHead;
164. }
165. //合并两个有序的单链表head1和head2,递归
166. public static Node mergeSortedListRec(Node head1,Node head2){
167. if(head1==null)return head2;
168. if(head2==null)return head1;
169. if(head1.value>head2.value){
170. head2.next=mergeSortedListRec(head2.next,head1);
171. return head2;
172. }
173. else{
174. head1.next=mergeSortedListRec(head1.next,head2);
175. return head1;
176. }
177. }
178. //对单链表进行排序,归并排序,在排序里面不建议选用递归的合并有序链表算法,如果链表长度较长,很容易出现栈溢出
179. public static Node listSort(Node head){
180. Node nex=null;
181. if(head==null||head.next==null)return head;
182. else if(head.next.next==null){
183. nex=head.next;
184. head.next=null;
185. }
186. else{
187. Node mid=getMiddleNode(head);
188. nex=mid.next;
189. mid.next=null;
190. }
191. return mergeSortedList(listSort(head),listSort(nex));//合并两个有序链表,不建议递归
192. }
193. //对单链表进行排序,插入排序
194. public Node insertionSortList(Node head) {
195. if(head==null||head.next==null)return head;
196. Node pnex=head.next;
197. Node pnex_nex=null;
198. head.next=null;
199. while(pnex!=null){
200. pnex_nex=pnex.next;
201. Node temp=head;
202. Node temp_pre=null;
203. while(temp!=null){
204. if(temp.value>pnex.value)break;
205. temp_pre=temp;
206. temp=temp.next;
207. }
208. if(temp_pre==null){
209. head=pnex;
210. pnex.next=temp;
211. }
212. else{
213. temp_pre.next=pnex;
214. pnex.next=temp;
215. }
216. pnex=pnex_nex;
217. }
218. return head;
219. }
220. //判断一个单链表中是否有环,快慢指针
221. public static boolean hasCycle(Node head){
222. boolean flag=false;
223. Node p1=head;
224. Node p2=head;
225. while(p1!=null&&p2!=null){
226. p1=p1.next;
227. p2=p2.next.next;
228. if(p2==p1){
229. flag=true;
230. break;
231. }
232. }
233. return flag;
234. }
235. //判断两个单链表是否相交,如果相交返回第一个节点,否则返回null
236. //如果单纯的判断是否相交,只需要看最后一个指针是否相等
237. public static Node isIntersect(Node head1,Node head2){
238. Node target=null;
239. if(head1==null||head2==null)return target;
240. int len1=getListLength(head1);
241. int len2=getListLength(head2);
242. if(len1>=len2){
243. for(int i=0;i<len1-len2;i++){
244. head1=head1.next;
245. }
246. }else{
247. for(int i=0;i<len2-len1;i++){
248. head2=head2.next;
249. }
250. }
251. while(head1!=null&&head2!=null){
252. if(head1==head2){
253. target=head1;
254. break;
255. }
256. else{
257. head1=head1.next;
258. head2=head2.next;
259. }
260. }
261. return target;
262. }
263. //已知一个单链表中存在环,求进入环中的第一个节点,利用hashmap,不要用ArrayList,因为判断ArrayList是否包含某个元素的效率不高
264. public static Node getFirstNodeInCycleHashMap(Node head){
265. Node target=null;
266. HashMap<Node,Boolean> map=new HashMap<Node,Boolean>();
267. while(head!=null){
268. if(map.containsKey(head))target=head;
269. else{
270. map.put(head, true);
271. }
272. head=head.next;
273. }
274. return target;
275. }
276. //已知一个单链表中存在环,求进入环中的第一个节点,不用hashmap
277. //用快慢指针,与判断一个单链表中是否有环一样,找到快慢指针第一次相交的节点,此时这个节点距离环开始节点的长度和链表投距离环开始的节点的长度相等
278. public static Node getFirstNodeInCycle(Node head){
279. Node fast=head;
280. Node slow=head;
281. while(fast!=null&&fast.next!=null){
282. slow=slow.next;
283. fast=fast.next.next;
284. if(slow==fast)break;
285. }
286. if(fast==null||fast.next==null)return null;//判断是否包含环
287. //相遇节点距离环开始节点的长度和链表投距离环开始的节点的长度相等
288. slow=head;
289. while(slow!=fast){
290. slow=slow.next;
291. fast=fast.next;
292. }//同步走
293. return slow;
294.
295. }
296. //给出一单链表头指针head和一节点指针delete,O(1)时间复杂度删除节点delete
297. //可惜采用将delete节点value值与它下个节点的值互换的方法,但是如果delete是最后一个节点,则不行,但是总得复杂度还是O(1)
298. public static void deleteNode(Node head,Node delete){
299. //首先处理delete节点为最后一个节点的情况
300. if(delete==null)return;
301. if(delete.next==null){
302. if(head==delete)head=null;
303. else{
304. Node temp=head;
305. while(temp.next!=delete){
306. temp=temp.next;
307. }
308. temp.next=null;
309. }
310. }
311. else{
312. delete.value=delete.next.value;
313. delete.next=delete.next.next;
314. }
315. return;
316. }
317.}
import java.util.HashMap;
import java.util.Scanner;
import java.util.Stack; /**
*
* @author kerryfish
* 关于java中链表的操作
* 1. 求单链表中结点的个数: getListLength
* 2. 将单链表反转: reverseList(遍历),reverseListRec(递归)
* 3. 查找单链表中的倒数第K个结点(k > 0): reGetKthNode
* 4. 查找单链表的中间结点: getMiddleNode
* 5. 从尾到头打印单链表: reversePrintListStack,reversePrintListRec(递归)
* 6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList, mergeSortedListRec
* 7. 对单链表进行排序,listSort(归并),insertionSortList(插入)
* 8. 判断一个单链表中是否有环: hasCycle
* 9. 判断两个单链表是否相交: isIntersect
* 10. 已知一个单链表中存在环,求进入环中的第一个节点: getFirstNodeInCycle, getFirstNodeInCycleHashMap
* 11. 给出一单链表头指针head和一节点指针delete,O(1)时间复杂度删除节点delete: deleteNode
*/
public class LinkedListSummary {
/**
* @param args
*
*/
public static class Node{
int value;
Node next;
public Node(int n){
this.value=n;
this.next=null;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
Node head=null;
if(in.hasNextInt()){
head=new Node(in.nextInt());
}
Node temp=head;
while(in.hasNextInt()){
temp.next=new Node(in.nextInt());
temp=temp.next;
}
in.close();
//int len=getListLength(head);
//Node reHead=reverseList(head);
//reHead=reverseListRec(reHead);
//Node node_k=reGetKthNode(head,3);
//Node mid=getMiddleNode(head);
//reversePrintListRec(head);
//reversePrintListStack(head);
//Node mergeHead=mergeSortedList(head,null);
//Node sortHead=listSort(head); }
//求单链表中结点的个数: getListLength
public static int getListLength(Node head){
int len=0;
while(head!=null){
len++;
head=head.next;
}
return len;
}
//将单链表反转,循环
public static Node reverseList(Node head){
if(head==null||head.next==null)return head;
Node pre=null;
Node nex=null;
while(head!=null){
nex=head.next;
head.next=pre;
pre=head;
head=nex;
}
return pre;
}
//将单链表反转,递归
public static Node reverseListRec(Node head){
if(head==null||head.next==null)return head;
Node reHead=reverseListRec(head.next);
head.next.next=head;
head.next=null;
return reHead;
}
//查找单链表中的倒数第K个结点(k > 0)
public static Node reGetKthNode(Node head,int k){
if(head==null)return head;
int len=getListLength(head);
if(k>len)return null;
Node target=head;
Node nexk=head;
for(int i=0;i<k;i++){
nexk=nexk.next;
}
while(nexk!=null){
target=target.next;
nexk=nexk.next;
}
return target;
}
//查找单链表的中间结点
public static Node getMiddleNode(Node head){
if(head==null||head.next==null)return head;
Node target=head;
Node temp=head;
while(temp!=null&&temp.next!=null){
target=target.next;
temp=temp.next.next;
}
return target;
}
//从尾到头打印单链表,递归
public static void reversePrintListRec(Node head){
if(head==null)return;
else{
reversePrintListRec(head.next);
System.out.println(head.value);
}
}
//从尾到头打印单链表,栈
public static void reversePrintListStack(Node head){
Stack<Node> s=new Stack<Node>();
while(head!=null){
s.push(head);
head=head.next;
}
while(!s.isEmpty()){
System.out.println(s.pop().value);
}
}
//合并两个有序的单链表head1和head2,循环
public static Node mergeSortedList(Node head1,Node head2){
if(head1==null)return head2;
if(head2==null)return head1;
Node target=null;
if(head1.value>head2.value){
target=head2;
head2=head2.next;
}
else{
target=head1;
head1=head1.next;
}
target.next=null;
Node mergeHead=target;
while(head1!=null && head2!=null){
if(head1.value>head2.value){
target.next=head2;
head2=head2.next;
}
else{
target.next=head1;
head1=head1.next;
}
target=target.next;
target.next=null;
}
if(head1==null)target.next=head2;
else target.next=head1;
return mergeHead;
}
//合并两个有序的单链表head1和head2,递归
public static Node mergeSortedListRec(Node head1,Node head2){
if(head1==null)return head2;
if(head2==null)return head1;
if(head1.value>head2.value){
head2.next=mergeSortedListRec(head2.next,head1);
return head2;
}
else{
head1.next=mergeSortedListRec(head1.next,head2);
return head1;
}
}
//对单链表进行排序,归并排序,在排序里面不建议选用递归的合并有序链表算法,如果链表长度较长,很容易出现栈溢出
public static Node listSort(Node head){
Node nex=null;
if(head==null||head.next==null)return head;
else if(head.next.next==null){
nex=head.next;
head.next=null;
}
else{
Node mid=getMiddleNode(head);
nex=mid.next;
mid.next=null;
}
return mergeSortedList(listSort(head),listSort(nex));//合并两个有序链表,不建议递归
}
//对单链表进行排序,插入排序
public Node insertionSortList(Node head) {
if(head==null||head.next==null)return head;
Node pnex=head.next;
Node pnex_nex=null;
head.next=null;
while(pnex!=null){
pnex_nex=pnex.next;
Node temp=head;
Node temp_pre=null;
while(temp!=null){
if(temp.value>pnex.value)break;
temp_pre=temp;
temp=temp.next;
}
if(temp_pre==null){
head=pnex;
pnex.next=temp;
}
else{
temp_pre.next=pnex;
pnex.next=temp;
}
pnex=pnex_nex;
}
return head;
}
//判断一个单链表中是否有环,快慢指针
public static boolean hasCycle(Node head){
boolean flag=false;
Node p1=head;
Node p2=head;
while(p1!=null&&p2!=null){
p1=p1.next;
p2=p2.next.next;
if(p2==p1){
flag=true;
break;
}
}
return flag;
}
//判断两个单链表是否相交,如果相交返回第一个节点,否则返回null
//如果单纯的判断是否相交,只需要看最后一个指针是否相等
public static Node isIntersect(Node head1,Node head2){
Node target=null;
if(head1==null||head2==null)return target;
int len1=getListLength(head1);
int len2=getListLength(head2);
if(len1>=len2){
for(int i=0;i<len1-len2;i++){
head1=head1.next;
}
}else{
for(int i=0;i<len2-len1;i++){
head2=head2.next;
}
}
while(head1!=null&&head2!=null){
if(head1==head2){
target=head1;
break;
}
else{
head1=head1.next;
head2=head2.next;
}
}
return target;
}
//已知一个单链表中存在环,求进入环中的第一个节点,利用hashmap,不要用ArrayList,因为判断ArrayList是否包含某个元素的效率不高
public static Node getFirstNodeInCycleHashMap(Node head){
Node target=null;
HashMap<Node,Boolean> map=new HashMap<Node,Boolean>();
while(head!=null){
if(map.containsKey(head))target=head;
else{
map.put(head, true);
}
head=head.next;
}
return target;
}
//已知一个单链表中存在环,求进入环中的第一个节点,不用hashmap
//用快慢指针,与判断一个单链表中是否有环一样,找到快慢指针第一次相交的节点,此时这个节点距离环开始节点的长度和链表投距离环开始的节点的长度相等
public static Node getFirstNodeInCycle(Node head){
Node fast=head;
Node slow=head;
while(fast!=null&&fast.next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast)break;
}
if(fast==null||fast.next==null)return null;//判断是否包含环
//相遇节点距离环开始节点的长度和链表投距离环开始的节点的长度相等
slow=head;
while(slow!=fast){
slow=slow.next;
fast=fast.next;
}//同步走
return slow; }
//给出一单链表头指针head和一节点指针delete,O(1)时间复杂度删除节点delete
//可惜采用将delete节点value值与它下个节点的值互换的方法,但是如果delete是最后一个节点,则不行,但是总得复杂度还是O(1)
public static void deleteNode(Node head,Node delete){
//首先处理delete节点为最后一个节点的情况
if(delete==null)return;
if(delete.next==null){
if(head==delete)head=null;
else{
Node temp=head;
while(temp.next!=delete){
temp=temp.next;
}
temp.next=null;
}
}
else{
delete.value=delete.next.value;
delete.next=delete.next.next;
}
return;
}
}

学习记录 java 链表知识的更多相关文章

  1. 学习记录-java基础部分(一)

    学习记录-java基础部分(一) 参考:GitHub上的知名项目:javaGuide : https://github.com/Snailclimb/JavaGuide/blob/master/doc ...

  2. 学习记录 java 值类型和引用类型的知识

    1. Java中值类型和引用类型的不同? [定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变 ...

  3. python核心编程学习记录之基础知识

    虽然对python的基础知识有所了解,但是为了更深入的学习,要对python的各种经典书籍进行学习 第一章介绍python的优缺点,略过 第二章介绍python起步,第三章介绍python基础,仅记录 ...

  4. JVM学习记录-Java内存模型(二)

    对于volatile型变量的特殊规则 关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制. 在处理多线程数据竞争问题时,不仅仅是可以使用synchronized关键字来实现,使用vo ...

  5. Python学习记录1-基础知识

    基础知识 基础 #简单记录了部分基础知识 #普通的打印字符串 >>> print("hello world") hello world ------------- ...

  6. 学习记录 java session保存用户登录

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  7. 学习记录 java 哈希

    哈希表(Hash Table,又叫散列表),是存储键值对(Key-value)的表,之所以不叫它Map(键值对一起存储一般叫做Map),是因为它下面的特性:它能把关键码(key)映射到表中的一个位置来 ...

  8. 学习记录 java泛型资料

    java泛型资料: 1. 概述在引入范型之前,Java类型分为原始类型.复杂类型,其中复杂类型分为数组和类.引入范型后,一个复杂类型就可以在细分成更多的类型.例如原先的类型List,现在在细分成Lis ...

  9. 学习记录 java随机数的产生机制

    java 随机数 一.在j2se里我们可以使用Math.random()方法来产生一个随机数,这个产生的随机数是0-1之间的一个double,我们可以把他乘以一定的数,比如说乘以100,他就是个100 ...

随机推荐

  1. vmware 没挂载光盘解决方案

    一定要选中上方的'已连接'

  2. 328. Odd Even Linked List

    Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...

  3. SQL 获取本年第几周

    根据输入的日期得出,算出是本年第几周 select datepart(week,getdate())

  4. Python分布式爬虫原理

    转载 permike 原文 Python分布式爬虫原理 首先,我们先来看看,如果是人正常的行为,是如何获取网页内容的. (1)打开浏览器,输入URL,打开源网页 (2)选取我们想要的内容,包括标题,作 ...

  5. [实变函数]3.1 外测度 (outer measure)

    1 并不是所有的集合都可求测度. 我们的想法是先对 $\bbR^n$ 中的任一集合定义一个``外 测度'' (outer measure), 然后再加上适当的条件 (Caratheodory 条件), ...

  6. ylbtech-LanguageSamples-Yield

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Yield 1.A,示例(Sample) 返回顶部 “Yield”示例 本示例演示如何创 ...

  7. JAVA 数组实例-求学生成绩的最大成绩,获取数组中的最大值、最小值

    实例: import java.util.*; //求学生最大成绩 public class Test{ public static void main(String[] args){ System. ...

  8. unset是不能清除保存在本地电脑上的cookie的,用于session就可以(弄了半天原来是这样)

    unset($_COOKIE["historyWord[$wordId]"]); 这样是不行的,unset只是将变量在脚本运行时注销,但是cookie是写在客户端的,下一次还是可以 ...

  9. Java多线程之新类库中的构件CountDownLatch

    使用CountDownLatch类 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count); ...

  10. iOS UIWebView 捕获403 、404错误

    #pragma mark -#pragma mark - UIWebView Delegate Methods- (BOOL)webView:(UIWebView *)webView shouldSt ...