8大排序算法---我熟知3(歸並排序/快速排序/堆排序)
排序算法:
快排: 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 { /** *View Code@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] <= pivotwhile (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); } }
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(歸並排序/快速排序/堆排序)