1. 程式人生 > >連結串列排序演算法java實現(連結串列的快速排序、插入排序、歸併排序)

連結串列排序演算法java實現(連結串列的快速排序、插入排序、歸併排序)

難易程度:★★

重要性:★★★

     連結串列的排序相對陣列的排序更為複雜些,也是考察求職者是否真正理解了排序演算法(而不是“死記硬背”)

  1. 連結串列的插入排序

    public  class LinkedInsertSort {
        static class ListNode {
            int val;
            ListNode next;
            ListNode(int x) {
                val = x;
                next = null;
            }
        }
    
        public static ListNode insertionSortList(ListNode head) {
            if(head==null||head.next==null)    return head;
    
            ListNode pre = head;//pre指向已經有序的節點
            ListNode cur = head.next;//cur指向待排序的節點
    
            ListNode aux = new ListNode(-1);//輔助節點
            aux.next = head;
    
            while(cur!=null){
                if(cur.val<pre.val){
                  //先把cur節點從當前連結串列中刪除,然後再把cur節點插入到合適位置
                    pre.next = cur.next;
    
                    //從前往後找到l2.val>cur.val,然後把cur節點插入到l1和l2之間
                    ListNode l1 = aux;
                    ListNode l2 = aux.next;
                    while(cur.val>l2.val){
                        l1 = l2;
                        l2 = l2.next;
                    }
                    //把cur節點插入到l1和l2之間
                    l1.next = cur;
                    cur.next = l2;//插入合適位置
    
                    cur = pre.next;//指向下一個待處理節點
    
                }else{
                    pre = cur;
                    cur = cur.next;
                }
            }
            return aux.next;
        }
    }
  2. 連結串列的快速排序
    public static ListNode quickSort(ListNode begin, ListNode end) {
            //判斷為空,判斷是不是隻有一個節點
            if (begin == null || end == null || begin == end)
                return begin;
            //從第一個節點和第一個節點的後面一個幾點
            //begin指向的是當前遍歷到的最後一個<= nMidValue的節點
            ListNode first = begin;
            ListNode second = begin.next;
    
            int nMidValue = begin.val;
            //結束條件,second到最後了
            while (second != end.next && second != null) {//結束條件
              //一直往後尋找<=nMidValue的節點,然後與fir的後繼節點交換
                if (second.val < nMidValue) {
                    first = first.next;
                    //判斷一下,避免後面的數比第一個數小,不用換的局面
                    if (first != second) {
                        int temp = first.val;
                        first.val = second.val;
                        second.val = temp;
                    }
                }
                second = second.next;
            }
            //判斷,有些情況是不用換的,提升效能
            if (begin != first) {
                int temp = begin.val;
                begin.val = first.val;
                first.val = temp;
            }
            //前部分遞迴
            quickSort(begin, first);
            //後部分遞迴
            quickSort(first.next, end);
            return begin;
        }
  3. 連結串列的歸併排序

    public ListNode mergeSort(ListNode head){
            if(head==null || head.next==null)    return head;
    
            ListNode mid = getMid(head);//獲取連結串列中間節點
    
            //把連結串列從之間拆分為兩個連結串列:head和second兩個子連結串列
            ListNode second = mid.next;
            mid.next = null;
    
            //對兩個子連結串列排序
            ListNode left = mergeSort(head);
            ListNode right = mergeSort(second);
    
            return merge(right,left);      
        }
    
        //兩個有序連結串列的歸併
        private ListNode merge(ListNode l1,ListNode l2){
          //輔助節點,排好序的節點將會連結到dummy後面
            ListNode dummy = new ListNode(0);
    
            ListNode tail = dummy;//tail指向最後一個排好序的節點
            while(l1!=null&&l2!=null){
                if(l1.val<=l2.val){
                    tail.next = l1;
                    l1 = l1.next;
                }else{
                    tail.next = l2;
                    l2 = l2.next;
                }
                tail = tail.next; //移動tail指標        
            }
    
            if(l1!=null)
                tail.next = l1;
            else
                tail.next = l2;
    
            return dummy.next;
    
        }
    
        //返回連結串列之間節點
        private ListNode getMid(ListNode head){
            if(head==null ||head.next==null)    return head;
    
            ListNode slow = head;
            ListNode faster = head.next;
            while(faster!=null&&faster.next!=null){
                slow = slow.next;
                faster = faster.next.next;
            }
            return slow;
        }

     轉自來自微信公眾號,一個專注應屆生網際網路求職分享的公眾號,公眾號ID:“菜鳥名企夢