数据结构_单链表操作总结

  1 package zz;
  2 
  3 import java.util.Stack;
  4 
  5 /**
  6  * 
  7  * @author zz
  8  * 关于java中链表的操作
  9  * 0. 向链表中插入新节点
 10  * 1. 求单链表中结点的个数: getListLength 
 11  * 2. 将单链表反转: reverseList(遍历),reverseListRec(递归) 
 12  * 3. 查找单链表中的倒数第K个结点(k > 0): reGetKthNode 
 13  * 4. 查找单链表的中间结点: getMiddleNode 
 14  * 5. 从尾到头打印单链表: reversePrintListStack,reversePrintListRec(递归) 
 15  * 6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList, mergeSortedListRec 
 16  * 7. 对链表的后半部分进行反转。reversePartNode
 17  * 8. 判断单链表是否存在环,isLoop。 使用两个指针,fast和low,fast一次走两步,low一次走一步。若存在环,总会有某个时刻fast和low指向同一节点
 18  * 9. 求出环的长度。getLoopLength().记录8中fast和low的遭遇点。然后让low走一圈环记数即可
 19  * 10. 对单链表进行排序,listSort(归并),insertionSortList(插入)
 20  * // 注释部分代码也经过调试正确
 21  */
 22 public class LinkedListSummary {
 23     public static class Node {
 24         int data;
 25         Node next;
 26         public Node(int value) {
 27             data = value;
 28             next = null;
 29         }
 30     }
 31     //向链表中插入新节点
 32     public static void addNode(Node head, int data) {
 33         Node newNode = new Node(data);
 34         if(head == null) {
 35             head = newNode;
 36             return;
 37         } else {
 38             Node temp = head;
 39             while(temp.next != null) {
 40                 temp = temp.next;
 41             }
 42             temp.next = newNode;            
 43         }
 44     }
 45     //输出链表的长度
 46     public static int getListLength(Node head) {
 47         int len = 0;
 48         //if(head == null) return 0;
 49         Node temp = head;
 50         while(temp != null) {
 51             len++;
 52             temp = temp.next;
 53         }
 54         System.out.println("输出链表长度:" + len);
 55         return len;
 56     }    
 57     //顺序打印链表数据 
 58     public static void print(Node head) {
 59        if(head == null) {
 60            System.out.println("链表为空");
 61            return;
 62        }
 63        Node temp = head;
 64        while(temp != null) {
 65            System.out.print(temp.data + " ");
 66            temp = temp.next;
 67        }
 68     }
 69     //方法1:使用栈反向遍历单链表
 70     public static void reversePrint(Node head) {
 71         if(head == null || head.next == null) return;
 72         Stack<Node> nodes = new Stack<Node>();
 73         Node temp = head;
 74         while(temp != null) {
 75             nodes.push(temp);
 76             temp = temp.next;
 77         }
 78         while(!nodes.isEmpty()) {
 79             //nodes.pop();
 80             System.out.print(nodes.pop().data + " ");
 81         }
 82     }
 83     //方法二:反向遍历单链表
 84     public static Node reversePrint2(Node head) {
 85         if(head == null || head.next == null) return head;
 86         Node pre = null;
 87         Node temp = null;
 88         while(head != null) {
 89             temp = head.next;
 90             head.next = pre;
 91             pre = head;
 92             head = temp;
 93         } 
 94         print(pre);
 95     //    System.out.println(head == null ? "空" : "非空");
 96         return pre;
 97     }    
 98     //递归反向遍历单链表
 99     public static Node reversePrintRec(Node head) {
100         if(head == null || head.next == null) {
101             System.out.println("链表遍历完成,只有head节点或为空链表");
102             return head;
103         }
104         Node reHead = reversePrintRec(head.next);
105          head.next.next = head;
106         head.next = null;
107         return head;
108     }
109     //从尾到头打印递归打印单链表
110     public static void reversePrintListRec(Node head) {
111         if(head == null) {
112             return;
113         } else {
114             reversePrintListRec(head.next);
115             System.out.print(head.data + ",");
116         }
117     }
118     //查找单链表的倒数第K个节点(k>0)
119     public static Node reGetKthNode(Node head, int k) {
120         int len = 0;
121         Node temp = head;
122         while(temp != null) {
123             len++;
124             temp = temp.next;
125         }
126         if(k > len) {
127             System.out.println("链表长度有限,小于K,找不到倒数第K个节点");
128             return null;
129         }
130         Node n1 = head;
131         Node n2 = head;
132         for(int i = 0; i < k; i++) {
133             n1 = n1.next;
134         }
135         while(n1 != null){
136             n2 = n2.next;
137             n1 = n1.next;
138         }
139         System.out.println(n2.data);
140         return n2;
141     }
142     //查找单链表的中间结点: getMiddleNode
143     public static Node getMiddleNode(Node head) {
144         if(head == null || head.next == null) return head;
145         Node n1 = head;
146         Node n2 = head;
147         while(n2 != null && n2.next != null) {
148             n1 = n1.next;
149             n2 = n2.next.next;
150         }
151         //System.out.println(n1.data);
152         return n1;
153     }
154     //已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList
155     public static Node mergeSortedList(Node head1, Node head2) {
156         if(head1 == null) return head2;
157         if(head2 == null) return head1;
158         Node target = null;
159         if(head1.data > head2.data) {
160             target = head2;
161             head2 = head2.next;
162         } else {
163             target = head1;
164             head1 = head1.next;
165         } 
166         target.next = null;
167         Node newHead = target;
168         while(head1 != null && head2 != null) {
169             if(head1.data > head2.data) {
170                 target.next = head2;
171                 head2 = head2.next;
172             } else {
173                 target.next = head1;
174                 head1 = head1.next;
175             }
176             target = target.next;
177             target.next = null;
178         }
179         if(head1 == null) {
180             target.next = head2;
181         } else {
182             target.next = head1; 
183         }
184         return newHead;
185     }
186     //已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序(递归实现): mergeSortedListRec
187     public static Node mergeSortedListRec(Node head1, Node head2) {
188         if(head1 == null) return head2;
189         if(head2 == null) return head1;
190         Node head = null;
191         if(head1.data > head2.data) {
192             head = head2;
193             head.next = mergeSortedListRec(head2.next, head1);
194         } else {
195             head = head1;
196             head.next = mergeSortedListRec(head1.next, head2);
197         }
198          return head;
199     }
200     //将链表的后半部分进行反转
201     public static Node reversePartNode(Node head){  
202         Node flag = head;
203         Node cur = null;
204         Node mid = getMiddleNode(head);
205         
206         while(flag.next != mid) {     //取出中间节点的 前一个节点并保存
207             flag = flag.next;
208         }
209         Node pre = null;
210         //System.out.println("----" + flag.data);
211         while(mid != null) {
212             cur = mid.next;
213             mid.next = pre; 
214             pre = mid;
215             mid = cur;
216         } 
217        
218         flag.next = pre;
219         print(head);
220 
221         return head;
222     }  
223     //判断链表是否存在环
224     public static boolean isLoop(Node head) {
225         if(head == null || head.next != null) return false;
226         Node fast = head;
227         Node low = head;
228         while(fast != null && fast.next != null) {
229             low = low.next;
230             fast = fast.next.next;
231             if(fast == low) break;
232         }
233         if(fast == null || fast.next == null) return false;
234         return true;
235     }
236     //求出环的长度
237     public static int getLoopLength(Node head) {
238         if(head == null || head.next != null) return 0;
239         Node fast = head;
240         Node low = head;
241         while(fast != null && fast.next != null) {
242             low = low.next;
243             fast = fast.next.next;
244             if(fast == low) break;
245         }
246         if(fast == null || fast.next == null) return 0;
247         else {
248             int loopLen = 1;
249             while(low.next != fast) {
250                 loopLen++;
251                 low = low.next;
252             }
253             return loopLen;
254         }
255         
256     }
257 /*  
258     //单链表排序
259     public static Node listSort(Node head) {
260         Node nex = null;
261         if(head == null || head.next == null) return head;
262         else if(head.next.next == null) {
263             nex = head.next;
264             head.next = null;
265         } else {
266             Node mid = getMiddleNode(head);
267             nex = mid.next;
268             mid.next = null;
269         }
270         print(mergeSortedList(listSort(head), listSort(nex)));
271         return mergeSortedList(listSort(head), listSort(nex));
272     }
273 */
274     public static void main(String[] args) {
275         Node head = new Node(0);
276         addNode(head, 6);
277         addNode(head, 2);
278         addNode(head, 1);
279         addNode(head, 4);
280         addNode(head, 3);
281         addNode(head, 5);
282     //    listSort(head);
283         System.out.println("顺序打印链表数据:");
284         print(head);
285         System.out.println();
286         System.out.println("反转单链表后半部分节点:");
287         reversePartNode(head);
288         System.out.println();
289         
290         if(isLoop(head)) {
291             System.out.println("存在环");
292         } else System.out.println("不存在环");
293         
294         Node head1 = new Node(10);
295         addNode(head1, 11);
296         addNode(head1, 12);
297         addNode(head1, 13);
298         addNode(head1, 14);
299         addNode(head1, 15);
300         addNode(head1, 16);
301         addNode(head1, 17);
302         addNode(head1, 18);
303         addNode(head1, 19);
304         addNode(head1, 20);
305         /*
306         System.out.println();
307         System.out.println("反转单链表后半部分节点:");
308         reversePartNode(head1);
309         System.out.println();
310         */
311         Node head2 = new Node(100);
312         for(int i = 0; i < 8; i++) {
313             addNode(head2, 100+i);
314         }
315         
316         Node head3 = new Node(1000);
317         for(int i = 0; i < 8; i++) {
318             addNode(head3, 1001+i);
319         }
320         
321         getListLength(head);
322         System.out.println("顺序打印链表数据:");
323         print(head);
324     /*
325     //    System.out.println();
326     //    System.out.println("使用栈反转链表:");
327     //    reversePrint(head);
328     //    System.out.println();
329     //    reversePrint2(head);
330     //    System.out.println();
331     //    System.out.println("递归反向遍历单链表");
332     //    System.out.println("----" + head.data);
333     //    reversePrintListRec(head);
334     //    System.out.println();
335     //    System.out.println("查找单链表的倒数第K个节点的值");
336     //    reGetKthNode(head, 3);
337     //    System.out.println();
338     //    System.out.println("查找单链表的中间节点的值");
339     //    getMiddleNode(head);
340     //    System.out.println();
341     //    System.out.println("合并两个单链表:");
342     //    Node mergeHead = mergeSortedList(head, head1);
343     //    print(mergeHead);
344     //    System.out.println();
345     //    System.out.println("递归实现合并两个单链表:");
346     //    Node mergeHeadRec = mergeSortedListRec(head2, head3);
347     //    print(mergeHeadRec);
348         */
349     } 
350 }
原文地址:https://www.cnblogs.com/zzsaf/p/7054144.html