import java.lang.reflect.Array; import java.util.Arrays; import java.util.stream.Collectors; import java.util.stream.Stream; public class BasicSortDemo { public static void main(String[] args) { int[] arr = {20, 33, 5, 45, 56, 6, 7, 9, 58, 4, 34, 34, 332, 8, 43, 74, 52};//Stream.of().collect(Collectors.toList()).toArray(); // int[] arr = {3, 4, 2, 5, 1};//Stream.of().collect(Collectors.toList()).toArray(); // BubbleSort(arr); // selectSort(arr); // insertSort(arr); // shellSort(arr); // insertSort_front2back(arr); // shellSort(arr); // mergeSort(arr); speedsort(arr); printArray(arr); } static void BubbleSort(int[] arr) { for (int i = 0; i < arr.length; i++) { for (int j = i + 1; j < arr.length; j++) { if (arr[i] > arr[j]) { swap(arr, i, j); } } } } //选择排序,每次都取最小的放在已排序数组后面 static void selectSort(int[] arr) { for (int i = 0; i < arr.length; i++) { int current = arr[i]; int minIndex = i; for (int j = i + 1; j < arr.length; j++) { if (arr[j] < current) { minIndex = j; current = arr[j]; } } //找到更小的,交换位置 if (minIndex > i) { swap(arr, i, minIndex); } } } //插入排序,对于未排序的,每次取出一个之后向前移动,直到找到比自己小的为止.插入 static void insertSort_back2front(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { int nSortedIndex = i + 1; while (nSortedIndex > 0 && arr[nSortedIndex] < arr[nSortedIndex - 1]) { swap(arr, nSortedIndex - 1, nSortedIndex); nSortedIndex--; } } } //从后向前, 每个值都遍历一次,并且都向前查找位置 static void insertSort_front2back(int[] arr) { for (int i = 0; i < arr.length; i++) { int nCurrent = arr[i]; int npre = i - 1; while (npre >= 0 && arr[npre] > nCurrent) { arr[npre + 1] = arr[npre]; npre--; } arr[npre + 1] = nCurrent; } } //希尔排序,简单插入排序的改进版,它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 static void shellSort(int[] arr) { int nStartGap = ((Double) (Math.floor((arr.length / 2)))).intValue(); for (int nStep = nStartGap; nStep > 0; nStep = nStep / 2) { //里面是隔着step个数的插入排序 for (int i = nStep; i < arr.length; i++) { int nCurrent = arr[i]; int nPre = i - nStep; //向前找位置 while (nPre >= 0 && nCurrent < arr[nPre]) { arr[nPre + nStep] = arr[nPre]; nPre = nPre - nStep; } arr[nPre + nStep] = nCurrent; } } } //#region 归并算法, 将数据一直拆分到每个数组只有一个元素, 然后再逐个合并数组 static void mergeSort(int[] arr) { int[] res = doMergeSort(arr); for (int i = 0; i < arr.length; i++) { arr[i] = res[i]; } } static int[] doMergeSort(int[] arr) { if (arr.length < 2) { return arr; } int middle = ((Double) Math.floor(arr.length / 2)).intValue(); int[] left = Arrays.copyOfRange(arr, 0, middle); int[] right = Arrays.copyOfRange(arr, middle, arr.length); // int[] arrT = mergeArray(doMergeSort(left), doMergeSort(right)); int[] arrT = mergeArray_2(doMergeSort(left), doMergeSort(right)); return arrT; } static int[] mergeArray_2(int[] left, int[] right) { System.out.println(""); System.out.println("left"); printArray(left); System.out.println("right"); printArray(right); int i = 0, j = 0, t = 0; int[] res = new int[left.length + right.length]; while (i < left.length && j < right.length) { if (left[i] <= right[j]) { res[t++] = left[i++]; } else { res[t++] = right[j++]; } } if (i >= left.length) { while (j < right.length) { res[t++] = right[j++]; } } if (j >= right.length) { while (i < left.length) { res[t++] = left[i++]; } } printArray(res); System.out.println("=====doen ===="); return res; } static int[] mergeArray(int[] left, int[] right) { System.out.println("left"); printArray(left); System.out.println("right"); printArray(right); System.out.println("========="); int[] res = new int[left.length + right.length]; int t = 0; int nRIghtFlag = 0; for (int i = 0; i < left.length; i++) { int nLeft = left[i]; boolean nLeftUsed = false; for (int j = nRIghtFlag; j < right.length; j++) { if (nLeft <= right[j]) { res[t++] = nLeft; nLeftUsed = true; break; } else { res[t++] = right[j]; nRIghtFlag++; } } if (!nLeftUsed) { res[t++] = nLeft; } } if (nRIghtFlag < right.length) { for (int i = nRIghtFlag; i < right.length; i++) { res[t++] = right[i]; } } printArray(res); return res; } //endregion static void speedsort(int[] arr) { speedSort_1(arr, 0, arr.length - 1); } static void speedSort_1(int[] arr, int start, int nend) { if (nend > start) { // int nMiddle = speedSortPartioner(arr, start, nend); // int nMiddle = speedSortPartioner_2(arr, start, nend); int nMiddle = speedSortPartioner_3(arr, start, nend); speedSort_1(arr, start, nMiddle); speedSort_1(arr, nMiddle + 1, nend); System.out.println(nMiddle); } } //方式一: //因为base为左边第一个元素, 所有遍历时先从右边开始,从右边找到第一个小于base的值,然后复制到左边low位置(覆盖第一个low也就是base位置) //然后从左边寻找第一个大于base的值,找到后移动到右边high位置(该位置为原来小于base的值), //如此往复,知道low不在前进了为止,此时使用base值覆盖low位置的值,完成第一次排序(小于base的都在前面,大于base的都在后面) static int speedSortPartioner(int[] arr, int low, int high) { int nBase = arr[low]; while (low < high) { while (low < high && arr[high] >= nBase) { high--; } arr[low] = arr[high]; //从左向右,知道找打大于base的数据 while (low < high && arr[low] <= nBase) { low++; } arr[high] = arr[low]; } arr[low] = nBase; System.out.println("low result " + low); printArray(arr); System.out.println(" "); System.out.println("done "); return low; } // //定义index变量,记录小于base的位置.起始位置为low //1.定义pointer指针从low追个遍历到high //2.如果pointer所指向位置小于base,则与index位置互换,index++ //(备注index-1位置肯定是最后一个小于base值的位置) //3.如此遍历整个low-high所有元素 //4.遍历结束后,互换low与index-1元素,这样保证所有小于base的值在左边,大于base的值在右边 static int speedSortPartioner_3(int[] arr, int low, int high) { int pointer = low + 1, j = high; int index = pointer, nBase = arr[low]; //从low+1开始替换,最后low要与index替换 while (pointer <= j) { if (arr[pointer] < nBase) { swap(arr, index, pointer); index++; } pointer++; } swap(arr, low, index - 1); return index - 1; } //快速排序方式二 //base值这里默认为数组第一个元素. //1.从右边找到第一个小于base的值,从左边找到第一个大于base的值 //2.交换low,high位置(注意是互换的两个元素分别是大于和小于base的值) //3.回到1,分别从右边和左边找到匹配的值,然后互换位置 //4.如果low位置不再变化,此时low和high可能指向同一个元素或者相邻的元素 //5.替换low位置与base的值,这样保证互换过的小于base的值都在前面,大于base的值都在后面 //6.完成了一次排序 static int speedSortPartioner_2(int[] arr, int low, int high) { int nLeftIndex = low; int nBase = arr[low]; while (low < high) { //找到右边第一个小的 while (low < high && arr[high] >= nBase) { high--; } //找到左边第一个大的 while (low < high && arr[low] <= nBase) { low++; } if (low < high) { swap(arr, low, high); } } //将base上的基数与low位置替换,不管low,high是否指向同一值,因为可以判断low位置一定小于base swap(arr, low, nLeftIndex); System.out.println("low result " + low); printArray(arr); System.out.println("done "); System.out.println(" "); return low; } static void selectSort_2(int[] arr) { } static void printArray(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); System.out.print(" "); } System.out.println(""); } static void swap(int[] arr, int from, int to) { int tmp = arr[to]; arr[to] = arr[from]; arr[from] = tmp; } }