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. Java的最大优势还是跨平台么?

    之前码农界有码农说Java的最大优势是跨平台,真的是这样么?其实当时网络没这么火爆的时候,确实是这样的,但现在这已然不是了. 跨平台还是Java的最大优势么? 有跨平台需求的仅仅是客户端应用,而不是服 ...

  2. SOA_环境安装系列5_Oracle ADF安装SOA Extensions(案例)

    2015-01-02 Created By BaoXinjian

  3. PLSQL_Oracle Object所有数据库对象类型汇总和简解(概念)

    Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable ...

  4. php 自带过滤和转义函数

    函数名 释义 介绍 htmlspecialchars 将与.单双引号.大于和小于号化成HTML格式 &转成&"转成"' 转成'<转成<>转成> ...

  5. C++模板元编程 - 1 基本数据类型和运算

    这是博客开通前几天做的,C++的模板没办法存方便的浮点数,算了. 基本类型的设计参考了vczh轮子叔模仿boost的MPL的设计. 话说template和typename写多了真是无限烦人啊,不得已定 ...

  6. Android系统onKeyDown监控/拦截/监听/屏蔽返回键、菜单键和Home键

    在Android系统中用来显示界面的组件(Component)为Activity,也就是说只有重写Activity的onKeyDown方法来监控/拦截/屏蔽系统的返回键(back).菜单键(Menu) ...

  7. Mac下配置JAVA_HOME

    http://blog.csdn.net/shallowgrave/article/details/39367119 闲来无事,装个Hbase玩玩,突然发现Mac下默认安装的JDK7,没有配置JAVA ...

  8. phpStudy Linux安装集成环境 (CentOS--7)

    phpStudy for Linux (lnmp+lamp一键安装包) phpStudy for Linux 支持Apache/Nginx/Tengine/Lighttpd, 支持php5.2/5.3 ...

  9. c#图片上绘制半透明矩形

    p.CreateGraphics().FillRectangle( ,Color.LightGreen)), iLeft, iTop, iRight - iLeft, iBottom - iTop); ...

  10. [Java] 01 String 内存分析

    public class StringTest{ public static void main(String[] args){ String str1 = new String("123& ...