一、堆排序
如果还不了解满二叉树、完全二叉树和最大堆(或大顶堆)的话,可以先了解一下。因为大顶堆要求根节点的元素大于其孩子,这样得到大顶堆的堆顶的元素肯定是
序列中的最大值。清楚这些,就很容易理解堆排序了:先构造大顶堆,将大顶堆中堆顶元素与序列中末尾元素交换。这样序列尾部的发生交换的元素是排列过的,剩下的未排列的元素重新构造大顶堆,继续执行上面步骤。
用简单的图来表示
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)); } }