大概花了一周的时间把八大基础排序过了一遍,这篇博文主要是用来回顾一下八大基础排序的要点和一些总结~html
回顾:git
总的来讲:快速排序是用得比较普遍的一个排序,也是常常出现的一个排序,应该重点掌握~github
思路:算法
n-1
趟排序,好比10个数,须要9趟排序代码实现要点:shell
//外层循环是排序的趟数 for (int i = 0; i < arrays.length -1 ; i++) { //每比较一趟就从新初始化为0 isChange = 0; //内层循环是当前趟数须要比较的次数 for (int j = 0; j < arrays.length - i - 1; j++) { //前一位与后一位与前一位比较,若是前一位比后一位要大,那么交换 if (arrays[j] > arrays[j + 1]) { temp = arrays[j]; arrays[j] = arrays[j + 1]; arrays[j + 1] = temp; //若是进到这里面了,说明发生置换了 isChange = 1; } } //若是比较完一趟没有发生置换,那么说明已经排好序了,不须要再执行下去了 if (isChange == 0) { break; } } System.out.println("公众号Java3y" + arrays);
思路:api
n-1
趟排序,好比10个数,须要9趟排序代码实现要点:数组
//外层循环控制须要排序的趟数 for (int i = 0; i < arrays.length - 1; i++) { //新的趟数、将角标从新赋值为0 pos = 0; //内层循环控制遍历数组的个数并获得最大数的角标 for (int j = 0; j < arrays.length - i; j++) { if (arrays[j] > arrays[pos]) { pos = j; } } //交换 temp = arrays[pos]; arrays[pos] = arrays[arrays.length - 1 - i]; arrays[arrays.length - 1 - i] = temp; } System.out.println("公众号Java3y" + arrays);
思路:微信
n-1
趟排序,好比10个数,须要9趟排序代码实现:数据结构
//临时变量 int temp; //外层循环控制须要排序的趟数(从1开始由于将第0位当作了有序数据) for (int i = 1; i < arrays.length; i++) { temp = arrays[i]; //若是前一位(已排序的数据)比当前数据要大,那么就进入循环比较[参考第二趟排序] while (i >= 1 && arrays[i - 1] > temp) { //日后退一个位置,让当前数据与以前前位进行比较 arrays[i] = arrays[i - 1]; //不断往前,直到退出循环 i--; } //退出了循环说明找到了合适的位置了,将当前数据插入合适的位置中 arrays[i] = temp; } System.out.println("公众号Java3y" + arrays);
思路:学习
代码实现:
/** * 快速排序 * * @param arr * @param L 指向数组第一个元素 * @param R 指向数组最后一个元素 */ public static void quickSort(int[] arr, int L, int R) { int i = L; int j = R; //支点 int pivot = arr[(L + R) / 2]; //左右两端进行扫描,只要两端尚未交替,就一直扫描 while (i <= j) { //寻找直到比支点大的数 while (pivot > arr[i]) i++; //寻找直到比支点小的数 while (pivot < arr[j]) j--; //此时已经分别找到了比支点小的数(右边)、比支点大的数(左边),它们进行交换 if (i <= j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; i++; j--; } } //上面一个while保证了第一趟排序支点的左边比支点小,支点的右边比支点大了。 //“左边”再作排序,直到左边剩下一个数(递归出口) if (L < j) quickSort(arr, L, j); //“右边”再作排序,直到右边剩下一个数(递归出口) if (i < R) quickSort(arr, i, R); }
思路:
代码实现:
public static void main(String[] args) { int[] arrays = {9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8}; mergeSort(arrays, 0, arrays.length - 1); System.out.println("公众号:Java3y" + arrays); } /** * 归并排序 * * @param arrays * @param L 指向数组第一个元素 * @param R 指向数组最后一个元素 */ public static void mergeSort(int[] arrays, int L, int R) { //若是只有一个元素,那就不用排序了 if (L == R) { return; } else { //取中间的数,进行拆分 int M = (L + R) / 2; //左边的数不断进行拆分 mergeSort(arrays, L, M); //右边的数不断进行拆分 mergeSort(arrays, M + 1, R); //合并 merge(arrays, L, M + 1, R); } } /** * 合并数组 * * @param arrays * @param L 指向数组第一个元素 * @param M 指向数组分隔的元素 * @param R 指向数组最后的元素 */ public static void merge(int[] arrays, int L, int M, int R) { //左边的数组的大小 int[] leftArray = new int[M - L]; //右边的数组大小 int[] rightArray = new int[R - M + 1]; //往这两个数组填充数据 for (int i = L; i < M; i++) { leftArray[i - L] = arrays[i]; } for (int i = M; i <= R; i++) { rightArray[i - M] = arrays[i]; } int i = 0, j = 0; // arrays数组的第一个元素 int k = L; //比较这两个数组的值,哪一个小,就往数组上放 while (i < leftArray.length && j < rightArray.length) { //谁比较小,谁将元素放入大数组中,移动指针,继续比较下一个 if (leftArray[i] < rightArray[j]) { arrays[k] = leftArray[i]; i++; k++; } else { arrays[k] = rightArray[j]; j++; k++; } } //若是左边的数组还没比较完,右边的数都已经完了,那么将左边的数抄到大数组中(剩下的都是大数字) while (i < leftArray.length) { arrays[k] = leftArray[i]; i++; k++; } //若是右边的数组还没比较完,左边的数都已经完了,那么将右边的数抄到大数组中(剩下的都是大数字) while (j < rightArray.length) { arrays[k] = rightArray[j]; k++; j++; } }
思路:
代码实现:
public static void main(String[] args) { int[] arrays = {6, 3, 8, 7, 5, 1, 2, 23, 4321, 432, 3,2,34234,2134,1234,5,132423, 234, 4, 2, 4, 1, 5, 2, 5}; for (int i = 0; i < arrays.length; i++) { //每完成一次建堆就能够排除一个元素了 maxHeapify(arrays, arrays.length - i); //交换 int temp = arrays[0]; arrays[0] = arrays[(arrays.length - 1) - i]; arrays[(arrays.length - 1) - i] = temp; } System.out.println("公众号:Java3y" + arrays); } /** * 完成一次建堆,最大值在堆的顶部(根节点) */ public static void maxHeapify(int[] arrays, int size) { for (int i = size - 1; i >= 0; i--) { heapify(arrays, i, size); } } /** * 建堆 * * @param arrays 看做是彻底二叉树 * @param currentRootNode 当前父节点位置 * @param size 节点总数 */ public static void heapify(int[] arrays, int currentRootNode, int size) { if (currentRootNode < size) { //左子树和右字数的位置 int left = 2 * currentRootNode + 1; int right = 2 * currentRootNode + 2; //把当前父节点位置当作是最大的 int max = currentRootNode; if (left < size) { //若是比当前根元素要大,记录它的位置 if (arrays[max] < arrays[left]) { max = left; } } if (right < size) { //若是比当前根元素要大,记录它的位置 if (arrays[max] < arrays[right]) { max = right; } } //若是最大的不是根元素位置,那么就交换 if (max != currentRootNode) { int temp = arrays[max]; arrays[max] = arrays[currentRootNode]; arrays[currentRootNode] = temp; //继续比较,直到完成一次建堆 heapify(arrays, max, size); } } }
思路:
代码思路:
gap = gap / 2
,只是比普通版插入排序多了这么一个for循环罢了,难度并不大/** * 希尔排序 * * @param arrays */ public static void shellSort(int[] arrays) { //增量每次都/2 for (int step = arrays.length / 2; step > 0; step /= 2) { //从增量那组开始进行插入排序,直至完毕 for (int i = step; i < arrays.length; i++) { int j = i; int temp = arrays[j]; // j - step 就是表明与它同组隔壁的元素 while (j - step >= 0 && arrays[j - step] > temp) { arrays[j] = arrays[j - step]; j = j - step; } arrays[j] = temp; } } }
思路:
代码实现:
public static void main(String[] args) { int[] arrays = {6, 4322, 432, 344, 55, 234, 45, 243, 5, 2, 4, 5, 6, 7, 3245, 345, 345, 234, 68, 65}; radixSort(arrays); System.out.println("公众号:Java3y" + arrays); } public static void radixSort(int[] arrays) { int max = findMax(arrays, 0, arrays.length - 1); //须要遍历的次数由数组最大值的位数来决定 for (int i = 1; max / i > 0; i = i * 10) { int[][] buckets = new int[arrays.length][10]; //获取每一位数字(个、10、百、千位...分配到桶子里) for (int j = 0; j < arrays.length; j++) { int num = (arrays[j] / i) % 10; //将其放入桶子里 buckets[j][num] = arrays[j]; } //回收桶子里的元素 int k = 0; //有10个桶子 for (int j = 0; j < 10; j++) { //对每一个桶子里的元素进行回收 for (int l = 0; l < arrays.length ; l++) { //若是桶子里面有元素就回收(数据初始化会为0) if (buckets[l][j] != 0) { arrays[k++] = buckets[l][j]; } } } } } /** * 递归,找出数组最大的值 * * @param arrays 数组 * @param L 左边界,第一个数 * @param R 右边界,数组的长度 * @return */ public static int findMax(int[] arrays, int L, int R) { //若是该数组只有一个数,那么最大的就是该数组第一个值了 if (L == R) { return arrays[L]; } else { int a = arrays[L]; int b = findMax(arrays, L + 1, R);//找出总体的最大值 if (a > b) { return a; } else { return b; } } }
对于排序的时间复杂度和稳定性网上的图也不少不少,我就随便找一张了(侵删)
要是对某个排序不太理解的同窗最好是到我写的单个文章中进行查阅,由于有分解的步骤~
我也将代码(包括分解过程)上传到了码云上了,算法和数据结构的代码我都往上面放了,欢迎star~后序还会写栈、队列相关的博文,敬请期待...
休闲时间:
参考资料:
若是文章有错的地方欢迎指正,你们互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:Java3y