常見的鏈表排序(Java版)


       上篇博客中講解了九大內部排序算法,部分算法還提供了代碼實現,但是那些代碼實現都是基於數組進行排序的,本篇博客就以鏈表排序實現幾種常見的排序算法,以饗讀者。

 

快速排序的鏈表實現

算法思想:對於一個鏈表,以head節點的值作為key,然后遍歷之后的節點,可以得到一個小於key的鏈表和大於等於key的鏈表;由此遞歸可以對兩個鏈表分別進行快速。這里用到了快速排序的思想即經過一趟排序能夠將小於key的元素放在一邊,將大於等於key的元素放在另一邊。

代碼實現:

 1     //快速排序
 2     public static void quickSort(ListNode begin, ListNode end){
 3         if(begin == null || begin == end)
 4             return;
 5         
 6         ListNode index = paration(begin, end);
 7         quickSort(begin, index);
 8         quickSort(index.next, end);
 9     }
10     
11     /**
12      * 划分函數,以頭結點值為基准元素進行划分
13      * @param begin
14      * @param end
15      * @return
16      */
17     public static ListNode paration(ListNode begin, ListNode end){
18         if(begin == null || begin == end)
19             return begin;
20         
21         int val = begin.val;  //基准元素
22         ListNode index = begin, cur = begin.next;
23         
24         while(cur != end){
25             if(cur.val < val){  //交換
26                 index = index.next;
27                 int tmp = cur.val;
28                 cur.val = index.val;
29                 index.val = tmp;
30             }
31             cur = cur.next;
32         }
33         
34         
35         begin.val = index.val;
36         index.val = val;
37         
38         return index;
39     }

歸並排序的鏈表實現

算法思想:單鏈表與數組相比只能順序訪問每個元素,因此在使用二路歸並排序時關鍵在於找到鏈表的中間結點將鏈表一分為二:可以利用快慢指針同時遍歷單鏈表,當步長為2的指針指向鏈表最后一個結點或者最后一個結點的下一個結點時,步長為1的指針即指向鏈表的中間結點。然后是兩個有序單鏈表的合並問題。時間復雜度為O(N*logN),空間復雜度為O(1)。

代碼實現:

 1     //歸並排序
 2     public static ListNode mergeSort(ListNode head){
 3         if(head == null || head.next == null)  //空鏈表或者只有單個結點
 4             return head;
 5         ListNode slow = head, fast = head.next;
 6         
 7         while(fast != null && fast.next != null){  //使用快慢指針尋找中間 結點
 8             slow = slow.next;
 9             
10             fast = fast.next;
11             if(fast.next != null)
12                 fast = fast.next;        
13         }
14         
15         ListNode ptr1 = slow.next;
16         slow.next = null;
17         
18         ListNode tmp1 = mergeSort(head);
19         ListNode tmp2 = mergeSort(ptr1);
20         return merge(tmp1, tmp2);
21     }
22     
23     
24     public static ListNode merge(ListNode start1,  ListNode start2){
25         ListNode header = new ListNode(-1);
26         ListNode pre = header;
27         
28         ListNode ptr1 = start1, ptr2 = start2;
29         while(ptr1 != null && ptr2 != null){
30             if(ptr1.val <= ptr2.val){
31                 pre.next = ptr1;
32                 pre = ptr1;
33                 ptr1 = ptr1.next;
34             }else{
35                 pre.next = ptr2;
36                 pre = ptr2;
37                 ptr2 = ptr2.next;
38             }
39         }
40         while(ptr1 != null){
41             pre.next = ptr1;
42             pre = ptr1;
43             ptr1 = ptr1.next;
44         }
45         
46         while(ptr2 != null){
47             pre.next = ptr2;
48             pre = ptr2;
49             ptr2 = ptr2.next;
50         }
51         
52         
53         return header.next;
54         
55     }

冒泡排序的鏈表實現

算法思想:依次比較相鄰的結點,如果是逆序的就交換兩個結點

代碼實現:

 1     //冒泡排序
 2     public static ListNode bubbleSort(ListNode head){
 3         if(head == null || head.next == null)  //鏈表為空或者僅有單個結點
 4             return head;
 5         
 6         ListNode cur = null, tail = null;
 7         
 8         cur = head;
 9         
10         while(cur.next != tail){
11             while(cur.next != tail){
12                 if(cur.val > cur.next.val){
13                     int tmp = cur.val;
14                     cur.val = cur.next.val;
15                     cur.next.val = tmp;
16                 }
17                 cur = cur.next;
18             }
19             
20             tail = cur;  //下一次遍歷的尾結點是當前結點(仔細琢磨一下里面的道道)
21             cur = head;     //遍歷起始結點重置為頭結點    
22         }
23         
24         return head;
25         
26         
27     }

先寫這幾種吧,想起來再更。。。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM