1. 程式人生 > >8大排序算法---我熟知3(歸並排序/快速排序/堆排序)

8大排序算法---我熟知3(歸並排序/快速排序/堆排序)

fit 數組 快排 -- 最後一個元素 should return src ram

排序算法:

快排: o(nlogn) o(1)不穩定

歸並:o(nlogn) o(n) 穩定

基數:

冒泡

睡眠

面條

烙餅

1、quicksort:

  • 返回條件:start >=end
  • private = a[start]+a[end]/2
  • while(left <= right)
  •   while(left <= right && a[left] < privot)
  •   while(left <= right && a[right] > privot)
技術分享
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); } }
View Code

2、mergesort :分治的思想 o(n) : 合並兩個數組

主函數:異常檢查

    創建新數組

mergesort(int[] temp, int start ,int end,int[] A)

  返回條件:start > end {return}

  左排;

  右排;

  merge()

merge(int[] temp, int start, int end, int[] A) {

// merge two sorted subarrays in A to temp array

  while(left <= mid && right <= end) {

    if A[start] < A[end] {temp[index++] = A[start++]}

    else :

  有一個剩余,左邊,右邊剩余

  while(left <= mid) : temp[index++] = A[left++]

// copy temp back to A

  for循環賦值回A  

}  

技術分享
public class Solution {
    /**
     * @param A an integer array
     * @return void
     */
    public void sortIntegers2(int[] A) {
        // use a shared temp array, the extra memory is O(n) at least
        int[] temp = new int[A.length];
        mergeSort(A, 0, A.length - 1, temp);
    }
    
    private void mergeSort(int[] A, int start, int end, int[] temp) {
        if (start >= end) {
            return;
        }
        
        int left = start, right = end;
        int mid = (start + end) / 2;

        mergeSort(A, start, mid, temp);
        mergeSort(A, mid+1, end, temp);
        merge(A, start, mid, end, temp);
    }
    
    private void merge(int[] A, int start, int mid, int end, int[] temp) {
        int left = start;
        int right = mid+1;
        int index = start;
        
        // merge two sorted subarrays in A to temp array
        while (left <= mid && right <= end) {
            if (A[left] < A[right]) {
                temp[index++] = A[left++];
            } else {
                temp[index++] = A[right++];
            }
        }
        while (left <= mid) {
            temp[index++] = A[left++];
        }
        while (right <= end) {
            temp[index++] = A[right++];
        }
        
        // copy temp back to A
        for (index = start; index <= end; index++) {
            A[index] = temp[index];
        }
    }
}
View Code

3、堆排序

重新理解堆排序:
堆排序步驟:
1)生成小根堆(大根堆)
先按照數組排(R[0...n-1]下標)序生成完全二叉樹,然後從最後一個非葉子節點(n/2 - 1)開始,把其當做是根節點,逐步向前調整(根節點是最小的),進行創建小根堆。
2)堆調整:
1. 取出小跟堆的頂點值,將其與堆中第N(N=n)個節點互換位置,即R[N-1]。
2. 此時小根堆被破壞,形成將得到新的無序區(R1,R2,......Rn-1)和新的有序區(Rn),且滿足R[1,2...n-1]>=R[n];由於交換後新的堆頂R[1]可能違反堆的性質,因此需要對當前無序區(R1,R2,......Rn-1)調整為新堆,然後再次將R[1]與無序區最後一個元素交換,得到新的無序區(R1,R2....Rn-2)和新的有序區(Rn-1,Rn)。不斷重復此過程直到有序區的元素個數為n-1,則整個排序過程完成。
最小堆排序後生成:逆序即:從大到小的排序
代碼:
//生成小根堆
/**
* 調整成最小堆
* @param arr 數組
* @param top 堆頂位置
* @param tail 堆未位置
*/
public static void fitToMinHeap(int[] arr, int top, int tail) {
int i = top;
int temp = arr[i];
int j = 2 * i + 1;//找到子節點
while (j < tail) {
if (j + 1 < tail && arr[j + 1] < arr[j])//找出左右子節點中的最小
j++;
if (arr[j] >= temp)//子節點都大於父節點則跳出
break;
arr[i] = arr[j];//將子節點向上移,即移到父節點
i = j;
j = 2 * i + 1;
}
arr[i] = temp;
}
//堆排序
public static void heapSort(int[] arr) {
int n = arr.length;
for (int j = n / 2 - 1; j >= 0; j--)//從最後一個非葉子節點開始,初始化生成數組表示的最小堆
fitToMinHeap(arr, j, n);
for (int i = n - 1; i > 0; i--) {//每次拿出堆的頂點值
//把堆中的頂點與a[i]點互換
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
fitToMinHeap(arr, 0, i);//交換後再對前i個節點進行最小堆化
}
}

8大排序算法---我熟知3(歸並排序/快速排序/堆排序)