一些常見的排序演算法(二)
阿新 • • 發佈:2018-12-12
一、堆排序
如果還不瞭解滿二叉樹、完全二叉樹和最大堆(或大頂堆)的話,可以先了解一下。因為大頂堆要求根節點的元素大於其孩子,這樣得到大頂堆的堆頂的元素肯定是
序列中的最大值。清楚這些,就很容易理解堆排序了:先構造大頂堆,將大頂堆中堆頂元素與序列中末尾元素交換。這樣序列尾部的發生交換的元素是排列過的,剩下的未排列的元素重新構造大頂堆,繼續執行上面步驟。
用簡單的圖來表示
import java.util.Arrays; public class HeapSort { public static void main(String[] args) {int[] array = {1, 4, 9, 12, 5, 7, 10, 22, 11, 32}; //1、構造大頂堆:從最後一個非葉子節點開始,從按從右至左、從下到上的順序遍歷 for(int i = array.length/2 - 1; i >= 0; i--) { heapSort(array, array.length, i); } for (int i = array.length - 1; i > 0; i--) { //2、最後一個非葉子節點和頭結點交換swap(array, i, 0); //3、將餘下的陣列重新構造大頂堆 heapSort(array, i, 0); } System.out.println(Arrays.toString(array)); } /** * 排序:(在length長度內)將父節點和其子節點比較,將最大值放到父節點 * @param array * @param length 要排序的陣列的長度 * @param i 索引為i的父節點*/ public static void heapSort(int[] array, int length, int i) { //最大值指標 int big = i; //左孩子 int left = 2 * i + 1; //右孩子 int right = left + 1; if(left <= length - 1 && array[left] > array[big]) { big = left; } if(right <= length - 1 && array[right] > array[big]) { big = right; } //指標指向交換的位置,遞迴 if(array[i] != array[big]) { swap(array, i, big); heapSort(array, length, big); } } public static void swap(int[] array, int a, int b) { int temp = array[a]; array[a] = array[b]; array[b]= temp; } }
二、快速排序
快速排序其實是一種分治法的思想,將問題分解和原問題類似的但規模小的問題,遞迴求解。快速排序直接說演算法的思想感覺不是很好理解,我是這樣看快速排序的:總是將一組序列的第一個值作為中間值(序列中中間值左邊的數都比中間值小,右邊的數都比中間值大),將中間值放到序列中正確的位置。下面我們再看快速排序的具體實現:
1、取一個數作為中間數
2、將序列中比它大的數全放右邊,比它小的數全放左邊
3、對中間數的左右邊的小序列重複執行第二步,直到小序列中只有一個數
只對序列進行一次取中間值排序:
程式碼:
import java.util.Arrays; public class QuickSort { /** * 序列中比某個數(arr[l])大的放arr[l]一邊,比它小的放arr[l]另一邊,然後返回這個數的索引下標 * @param arr * @param l 從左開始的索引下標 * @param r 從右開始的索引下標 * @return */ public static int position(int[] arr, int l, int r) { int pointer = arr[l]; while (l < r) { while (l < r && arr[r] >= pointer) { r--; } //這個數比pointer小,把這個數放arr[l]另一邊 if (arr[r] < pointer) { arr[l] = arr[r]; l++; } while (l < r && arr[l] <= pointer) { l++; } //這個數比pointer大,把這個數放arr[l]另一邊 if (arr[l] > pointer) { arr[r] = arr[l]; r--; } } arr[l] = pointer; return l; } /** * 分治法思想:將問題分解和原問題類似的但規模小的問題,遞迴求解 * @param arr * @param i * @param j */ public static void sort(int[] arr, int i, int j) { if(i < j) { int k = position(arr, i, j); System.out.println("i:" + i); System.out.println("j:" + j); sort(arr, i, k - 1); sort(arr, k + 1, j); } } public static void main(String args[]) { int arr[] = { 6, 10, 3, 8, 9, 1, 9 }; int n = arr.length; //position(arr, 0, arr.length - 1); sort(arr, 0, n - 1); System.out.println(Arrays.toString(arr)); } }