快速排序
我们会以最左边的元素作为标准,
从高位取值和他比较,找到高位比他小的元素和low互换,如果比他大则坐标减一继续找
从低位取值找到比他大的元素,和high互换填补到high的位置,如果比他小则继续找
直到low = high循环结束,此时low或者high的坐标就是standard的坐标,返回之后继续递归
public static int parition(int[] arr, int low, int high) {int standard = arr[low];while (high > low) {while (high > low && arr[high] >= standard) {high--;}arr[low] = arr[high];while (high > low && arr[low] <= standard) {low++;}arr[high] = arr[low];}arr[low] = standard;return low; } 这里需要注意:必须要检查from要小于等于end public static void quickSort(int[] arr, int from, int end) {if (arr.length <= 1 || from >= end) {return;}int partition = parition(arr, from, end);quickSort(arr, from, partition - 1);quickSort(arr, partition + 1, end); }
归并排序
主体思想是先把数组分为不可分的整体每个整体看作一个数组,然后数组合并排序然后再合并最终变成一整个排序好的数组。但是直接这样可能不太好理解。
可以先用二分的方式把数组分成两个部分,然后再二分,直到不可分,然后merge
public static void mergeSort(int[] arr) {if (arr.length < 2) {return;}dichotomy(arr, 0, arr.length - 1); } public static void dichotomy(int[] arr, int low, int high) {if (high <= low) {return;}int mid = low + (high - low) / 2;// 继续二分dichotomy(arr, low, mid);dichotomy(arr, mid + 1, high);merge(arr, low, mid, high); }
当有任意一方到头了,则另一方全部灌入目标数组
public static void merge(int[] arr, int low, int mid, int high) {int leftIndex = low;int rightIndex = mid + 1;int[] result = new int[high - low + 1];for(int i = 0; i < result.length; i++) {// 两边都还没到头则互相比较if (leftIndex <= mid && rightIndex <= high) {if (arr[leftIndex] <= arr[rightIndex]) {result[i] = arr[leftIndex];leftIndex++;} else {result[i] = arr[rightIndex];rightIndex++;}} else if (leftIndex <= mid) {// 右边到头了result[i] = arr[leftIndex];leftIndex++;} else {// 左边到头了result[i] = arr[rightIndex];rightIndex++;}} // 目标数组归入原数组for(int i = 0; i < result.length;i++) {arr[i + low] = result[i];} }
堆排序
通过大根堆的性质,把最大值放到堆顶,然后和数组最后一位互换,堆长度--
整个过程堆长度要始终传入。
数组元素i的左右堆元素分别为 2*i + 1,2*i+2
数组最大非叶子节点为(length - 2)/2
public static void heapsort(int[] arr) {if (arr.length < 2) {return;}int heapLen = arr.length;for (int i = arr.length - 1; i > 0; i--) {findBiggestHeap(arr, heapLen);// 此时和大根堆的0位置互换swap(arr, 0, i);heapLen--;} }
public static void findBiggestHeap(int[] arr, int heapLen) {int notLeafNode = (heapLen - 2) / 2;int leftNode, rightMode;for(int i = notLeafNode; i >= 0;i--) {leftNode = i*2 + 1;rightMode = leftNode + 1;leftRightCompare(arr, leftNode, rightMode, heapLen, i);} } public static void downAdjust(int[] arr, int i, int heapLen) {int leftNode = i*2 + 1;int rightMode = leftNode + 1;leftRightCompare(arr, leftNode, rightMode, heapLen, i); }
public static void leftRightCompare(int[] arr, int leftNode, int rightMode, int heapLen, int i) {if (rightMode < heapLen) {// 有两个节点if (arr[leftNode] > arr[i] && arr[leftNode] >= arr[rightMode]) {// 左节点最大swap(arr, leftNode, i);// i节点下放之后还得处理downAdjust(arr, leftNode, heapLen);} else if (arr[rightMode] > arr[i] && arr[rightMode] > arr[leftNode]) {// 右节点最大swap(arr, rightMode, i);// i节点下放之后还得处理downAdjust(arr, rightMode, heapLen);}} else if (leftNode < heapLen) {// 仅有左边的节点if (arr[leftNode] > arr[i]) {swap(arr, leftNode, i);// i节点下放之后还得处理downAdjust(arr, leftNode, heapLen);}} }
半插入排序
我的半插入排序习惯从第三位开始排序,即默认前两个位置已经有序
public static void dInsertSort(int[] arr) {if (arr.length < 2) {return;}if(arr[0] > arr[1]) {swap(arr, 0, 1);}int mid, low, high, tmp;for(int i = 2; i < arr.length; i++) {if (arr[i] >= arr[i-1]) {continue;}low = 0;high = i;mid = low + (high - low)/2;while (high >= low) {if (arr[i] > arr[mid]) {low = mid + 1;} else {high = mid - 1;}mid = low + (high - low)/2;}// 当low比high要大的时候// 移动数组,1,4,5,3 => 1,4,4,5tmp = arr[i];moveArr(arr, low, i);// 1,4,4,5 -> 1,3,4,5arr[low] = tmp;} }
public static void moveArr(int[] arr, int low, int to) {for(int i = to; i > low; i--) {arr[i] = arr[i - 1];} }
桶排序
希尔排序
public static void shell(int[] arr) {int gap = arr.length >> 1;while (gap >= 1) {shell1(arr, gap);if(gap == 1) {break;}gap = gap >> 1;} } public static void shell1(int[] arr, int gap) {for(int i = 0; i < gap; i++) {isGap(arr, gap);} } public static void isGap(int[] arr, int gap) {for(int i = gap; i < arr.length; i += gap) {for(int j = i; j > 0; j -= gap) {if(arr[j - gap] > arr[j]) {swap(arr, j - gap, j);}}} }