• 各种排序笔记---基于比较排序部分


    1. 选择排序 selection sort

      大循环 从左到右每次以一个点开始扫描array

        小循环 找到从当前起始点开始的最小值

      时间复杂度为O(N^2)

    //selection sort an array array[]
    public class Solution {
      public int[] solve(int[] array) {
        
        if (array == null || array.length == 0) {
          return array;
        }
        
        for (int i = 0; i < array.length - 1; i++) {
          int gobalMin = i;
          for (int j = i + 1; j < array.length; j++) {
            if (array[j] < array[gobalMin]) {
              gobalMin = j;
            }
          }
          swap(array, i, gobalMin);
        }
        return array;
      }
      
      private void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
      }
    }
    Selection sort

    2. 归并排序 Merge sort

    归并排序是基于一种被称为“分治”(divide and conquer)的策略。

    Merge sort array:

    public int[] mergeSort(int[] array) {
                if (array == null || array.length == 0) {
                    return array;
                }
    
                int[] temp = new int[array.length];
                mergeSortHelper(array, 0, array.length - 1, temp);
                return array;
            }
    
            private void mergeSortHelper(int[] array, int start, int end, int[] temp) {
                if (start == end) {
                    return;
                }
    
                int mid = start + (end - start) / 2;
    
                mergeSortHelper(array, start, mid, temp);
                mergeSortHelper(array, mid + 1, end, temp);
                merge(array, start, mid, end, temp);
            }
    
            private void merge(int[] array, int start, int mid, int end, int[] temp) {
                int left = start;
                int right = mid + 1;
                int index = start;
    
                while (left <= mid && right <= end) {
                    if (array[left] < array[right]) {
                        temp[index++] = array[left++];
                    } else {
                        temp[index++] = array[right++];
                    }
                }
    
                while (left <= mid) {
                    temp[index++] = array[left++];
                }
    
                while (right <= end) {
                    temp[index++] = array[right++];
                }
                for (index = start; index <= end; index++) {
                    array[index] = temp[index];
                }
            }
    merge sort array

    复杂度分析:

                             1 2 3 4 5 6 7 8 

                              /                当前层拆分需要劈1刀 O(1)

                           1 2 3 4

                           /                 当前层拆分需要劈2刀  O(2)

                         12                      ...

                        /

                       1                        当前层拆分需要劈n  /2刀

                      1 + 2 + 4 + 8+ ... + n/2 -> n  = O(n)  可以这样理解,终极状态下每个数字被切分成一个单位,n个数字,需要被切n-1刀

                      所以devide and conquer的上半部分的时间复杂度是O(n) 而不是log(n)

                      空间复杂度:考虑计算机里面只要保存的额外开销,其实是粉色部分,因为在任意时刻,计算机只有一个确定的状态,call stack在同一个确定的层只能保留部分的结果。比如最底层只能保留1,或者保留2,而不会1,2同时在栈里面!

                      所以空间复杂度:1 + 2 + 4 + 8 + ... + n = O(2n) = O(n)

                        ==============================================

                devide and conquer的上半部分,merge 部分, totoal time complexity is O(nlogn):

                          1      2         3     4       5    6      7       8

                           /                /             /              /            this level time complexity is O(n)

                           12               34            56            78

                                  /                         /             this level time complexity is O(n)

                             1234        5678

                                                          /              this level time complexity is O(n)

                                 12345678

    3. 快速排序

    Array quick sort:

    重点在于理解左右两个挡板的物理意义!!!

    a. [0,....., left]: left 的左侧(不包含left)全部为比pivot小的数

    b. [left, right]: left 和 right之间为未探索的区域

    c. [right, ..... n-1]: right的右侧(不包含)全部为比pivot大或者等于的数字

    public class Solution {
        /**
         * @param A an integer array
         * @return void
         */
        public void sortIntegers2(int[] A) {
            quickSort(A, 0, A.length - 1);
        }
        
        private void quickSort(int[] A, int start, int end) {
            if (start >= end) {
                return;
            }
            
            int left = start, right = end;
            // key point 1: pivot is the value, not the index
            int pivot = A[(start + end) / 2];
    
            // key point 2: every time you compare left & right, it should be 
            // left <= right not left < right
            while (left <= right) {
                // key point 3: A[left] < pivot not A[left] <= pivot
                while (left <= right && A[left] < pivot) {
                    left++;
                }
                // key point 3: A[right] > pivot not A[right] >= pivot
                while (left <= right && A[right] > pivot) {
                    right--;
                }
                if (left <= right) {
                    int temp = A[left];
                    A[left] = A[right];
                    A[right] = temp;
                    
                    left++;
                    right--;
                }
            }
            
            quickSort(A, start, right);
            quickSort(A, left, end);
        }
    }
    array quick sort

    伪代码:

    function quicksort(q)
         var list less, pivotList, greater
         if length(q) ≤ 1 {
             return q
         } else {
             select a pivot value pivot from q
             for each x in q except the pivot element
                 if x < pivot then add x to less
                 if x ≥ pivot then add x to greater
             add pivot to pivotList
             return concatenate(quicksort(less), pivotList, quicksort(greater))
         }
    

    Linkedlist quick sort

    public class Solution {
        public ListNode sortList(ListNode head) {
            if (head == null || head.next == null) {
                return head;
            }
            
            ListNode mid = findMedian(head); // O(n)
            
            //new three dummmy node with a tail point to it
            ListNode leftDummy = new ListNode(0), leftTail = leftDummy;
            ListNode rightDummy = new ListNode(0), rightTail = rightDummy;
            ListNode middleDummy = new ListNode(0), middleTail = middleDummy;
            
            //sprate to three part 
            while (head != null) {
                if (head.val < mid.val) {
                    leftTail.next = head;
                    leftTail = head;
                } else if (head.val > mid.val) {
                    rightTail.next = head;
                    rightTail = head;
                } else {
                    middleTail.next = head;
                    middleTail = head;
                }
                head = head.next;
            }
            
            //make the tail to null
            leftTail.next = null;
            middleTail.next = null;
            rightTail.next = null;
            
            //recurisive do the sort
            ListNode left = sortList(leftDummy.next);
            ListNode right = sortList(rightDummy.next);
            
            //connect the three parts together
            return concat(left, middleDummy.next, right);
        }
        private static ListNode findMedian(ListNode head) {
            ListNode fast = head.next;
            ListNode slow = head;
            while (fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
            return slow;
        }
        private static ListNode concat(ListNode left, ListNode mid, ListNode right) {
            ListNode dummy = new ListNode(0), dummyTail = dummy;
            dummyTail = connect(dummyTail, left);
            dummyTail = connect(dummyTail, mid);
            dummyTail = connect(dummyTail, right);
            return dummy.next;
        }
        private static ListNode connect(ListNode dummyTail, ListNode current) {
             while (current != null) {
                dummyTail.next = current;
                dummyTail = dummyTail.next;
                current = current.next;
             }
             return dummyTail;
        }
    }
    sortList

    相关题目整理: //to do 

  • 相关阅读:
    Python动态展示遗传算法求解TSP旅行商问题
    MOEAD算法中均匀权向量的实现---Python
    HDU 5294 多校第一场1007题 最短路+最小割
    POJ 3261 Milk Patterns sa+二分
    HDU 4292 FOOD 2012 ACM/ICPC Asia Regional Chengdu Online
    CodeForces 201A Clear Symmetry
    POJ 1679 The Unique MST 确定MST是否唯一
    POJ 3268 Silver Cow Party 最短路 基础题
    POJ 2139 SIx Degrees of Cowvin Bacon 最短路 水題
    POJ2229 Sumsets 基礎DP
  • 原文地址:https://www.cnblogs.com/jiangchen/p/5935343.html
Copyright © 2020-2023  润新知