常见排序算法原理及java实现
最近整理了几种常见排序算法,基于java代码实现,都只是点干货,没有过多原理分析,后期会持续更新
/** * * 冒泡排序 @author :manzi Create Date : 2019年4月29日 下午6:55:20 * * 原理:比较两个相邻的元素,将值大的元素交换至右端。 * * 1思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。 * 2即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。 * 3然后比较第2个数和第3个数,将小数放前,大数放后, * 4如此继续,直至比较最后两个数,将小数放前,大数放后。 * 5重复第一趟步骤,直至全部排序完成。 */ public static void bubbleSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { for (int j = i + 1; j < arr.length; j++) { if (arr[i] > arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } } /** * * 插入排序 @author :manzi Create Date : 2019年4月29日 下午6:55:46 * * 原理:将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据, * 算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。 * * 1从第一个元素开始,该元素可以认为已经被排序 * 2取出下一个元素,在已经排序的元素序列中从后向前扫描 * 3如果该元素(已排序)大于新元素,将该元素移到下一位置 * 4重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 * 5将新元素插入到该位置后 * 6重复步骤2~5 * */ public static void insertSortFor(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { for (int j = i + 1; j > 0; j--) { if (arr[j] < arr[j - 1]) { int temp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = temp; } else { break; } } } } public static void insertSortWhile(int[] arr) { for (int i = 1; i < arr.length; i++) { int temp = arr[i]; while (i > 0 && temp < arr[i - 1] ) { arr[i] = arr[i - 1]; i--; } arr[i] = temp; } } /** * * 选择排序 @author :manzi Create Date : 2019年4月29日 下午6:56:30 * * 原理:选择排序,从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列 * * 1.将序列分为两段,有序前列[0,r)和无序后列[r,n-1] * 2.在无序后列中查找最大元素s=A[m],记住其所在位置 * 3.将无序后列中的最大元素与无序前列的首位元素进行交换 * 4.循环停止标识:无序后列只剩余最后一个元素 */ public static void selectSort(int[] arr) { for (int i = 0; i < arr.length; i++) { int k = i; for (int j = i; j < arr.length; j++) { if (arr[j] < arr[k]) { k = j; } } if (k != i) { int temp = arr[i]; arr[i] = arr[k]; arr[k] = temp; } } } /** * * 快速排序 @author :manzi Create Date : 2019年4月29日 下午6:56:30 * * 原理:底层是冒泡排序。它是通过一趟排序,将一组数据分为两部分, * 其中一部分要比另一部分的所有数据都要小,然后再用此方法分别进行快速排序,以达到一组数据的有序排序 * * 1.先从数列中取出一个数作为基准数。 * 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。 * 3.再对左右区间重复第二步,直到各区间只有一个数。 * * 挖坑填数+分治法+递归 */ public static void quickSort(int[] arr, int left, int right) { if (left >= right) { return; } int i = left; int j = right; int dest = arr[i]; while (i < j) { while (i < j && dest <= arr[j]) { j--; } if (i < j) { arr[i++] = arr[j]; } while (i < j && dest > arr[i]) { i++; } if (i < j) { arr[j--] = arr[i]; } } arr[i] = dest; quickSort(arr, left, i - 1); quickSort(arr, i + 1, right); } /** * * 归并排序 @author :manzi Create Date : 2019年4月29日 下午6:56:30 * * 原理:排序一个数组,把数组从中间分为两部分,然后对前后两部分进行分别排序。最后把排序好的两部分都合并在一起,在合并的时候也会进行排序 * * 1申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 * 2设定两个指针,最初位置分别为两个已经排序序列的起始位置 * 3比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 * 4重复步骤3直到某一指针达到序列尾 * 5将另一序列剩下的所有元素直接复制到合并序列尾 * 6将临时数组中元素替换原数组元素 */ public static void mergeSort(int[] arr, int low, int high) { int middle = (high + low) / 2; if (low < high) { mergeSort(arr, low, middle); mergeSort(arr, middle + 1, high); mergeSort(arr, low, middle, high); } } public static void mergeSort(int[] arr, int low, int middle, int high) { int i = low; int j = middle + 1; int k = 0; int temp[] = new int[high - low + 1]; while (i <= middle && j <= high) { if (arr[i] < arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; } } while (i <= middle) { temp[k++] = arr[i++]; } while (j <= high) { temp[k++] = arr[j++]; } while (high >= low) { arr[high--] = temp[--k]; } }