冒泡排序
import java.util.Arrays; public class BubbleSort { public static void sort(int array[]) { int tmp = 0; //记录最后一次交换的位置 int lastExchangeIndex = 0; //无序数列的边界,每次比较只需要比到这里为止 int sortBorder = array.length - 1; for(int i = 0; i < array.length; i++) { //有序标记,每一轮的初始是true boolean isSorted = true; for(int j = 0; j < sortBorder; j++) { if(array[j] > array[j+1]) { tmp = array[j]; array[j] = array[j+1]; array[j+1] = tmp; //有元素交换,所以不是有序,标记变为false isSorted = false; //把无序数列的边界更新为最后一次交换元素的位置 lastExchangeIndex = j; } } sortBorder = lastExchangeIndex; if(isSorted){ break; } } } public static void main(String[] args){ int[] array = new int[]{3,4,2,1,5,6,7,8}; sort(array); System.out.println(Arrays.toString(array)); } }
鸡尾酒排序
import java.util.Arrays; public class CockTailSort { public static void sort(int array[]) { int tmp = 0; for(int i=0; i<array.length/2; i++) { //有序标记,每一轮的初始是true boolean isSorted = true; //奇数轮,从左向右比较和交换 for(int j=i; j<array.length-i-1; j++) { if(array[j] > array[j+1]) { tmp = array[j]; array[j] = array[j+1]; array[j+1] = tmp; //有元素交换,所以不是有序,标记变为false isSorted = false; } } if(isSorted){ break; } //偶数轮之前,重新标记为true isSorted = true; //偶数轮,从右向左比较和交换 for(int j=array.length-i-1; j>i; j--) { if(array[j] < array[j-1]) { tmp = array[j]; array[j] = array[j-1]; array[j-1] = tmp; //有元素交换,所以不是有序,标记变为false isSorted = false; } } if(isSorted){ break; } } } public static void main(String[] args){ int[] array = new int[]{2,3,4,5,6,7,8,1}; sort(array); System.out.println(Arrays.toString(array)); } }
快速排序
import java.util.Arrays; public class QuickSort { public static void quickSort(int[] arr, int startIndex, int endIndex) { // 递归结束条件:startIndex大等于endIndex的时候 if (startIndex >= endIndex) { return; } // 得到基准元素位置 int pivotIndex = partition(arr, startIndex, endIndex); // 根据基准元素,分成两部分递归排序 quickSort(arr, startIndex, pivotIndex - 1); quickSort(arr, pivotIndex + 1, endIndex); } /** * 分治(双边循环法) * @param arr 待交换的数组 * @param startIndex 起始下标 * @param endIndex 结束下标 */ private static int partition(int[] arr, int startIndex, int endIndex) { // 取第一个位置的元素作为基准元素(也可以选择随机位置) int pivot = arr[startIndex]; int left = startIndex; int right = endIndex; while( left != right) { //控制right指针比较并左移 while(left<right && arr[right] > pivot){ right--; } //控制left指针比较并右移 while( left<right && arr[left] <= pivot) { left++; } //交换left和right指向的元素 if(left<right) { int p = arr[left]; arr[left] = arr[right]; arr[right] = p; } } //pivot和指针重合点交换 arr[startIndex] = arr[left]; arr[left] = pivot; return left; } /** * 分治(单边循环法) * @param arr 待交换的数组 * @param startIndex 起始下标 * @param endIndex 结束下标 */ private static int partitionV2(int[] arr, int startIndex, int endIndex) { // 取第一个位置的元素作为基准元素(也可以选择随机位置) int pivot = arr[startIndex]; int mark = startIndex; for(int i=startIndex+1; i<=endIndex; i++){ if(arr[i]<pivot){ mark ++; int p = arr[mark]; arr[mark] = arr[i]; arr[i] = p; } } arr[startIndex] = arr[mark]; arr[mark] = pivot; return mark; } public static void main(String[] args) { int[] arr = new int[] {4,4,6,5,3,2,8,1}; quickSort(arr, 0, arr.length-1); System.out.println(Arrays.toString(arr)); } }
使用栈快速排序
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Stack; public class QuickSortWithStack { public static void quickSort(int[] arr, int startIndex, int endIndex) { // 用一个集合栈来代替递归的函数栈 Stack<Map<String, Integer>> quickSortStack = new Stack<Map<String, Integer>>(); // 整个数列的起止下标,以哈希的形式入栈 Map rootParam = new HashMap(); rootParam.put("startIndex", startIndex); rootParam.put("endIndex", endIndex); quickSortStack.push(rootParam); // 循环结束条件:栈为空时结束 while (!quickSortStack.isEmpty()) { // 栈顶元素出栈,得到起止下标 Map<String, Integer> param = quickSortStack.pop(); // 得到基准元素位置 int pivotIndex = partition(arr, param.get("startIndex"), param.get("endIndex")); // 根据基准元素分成两部分, 把每一部分的起止下标入栈 if(param.get("startIndex") < pivotIndex -1){ Map<String, Integer> leftParam = new HashMap<String, Integer>(); leftParam.put("startIndex", param.get("startIndex")); leftParam.put("endIndex", pivotIndex -1); quickSortStack.push(leftParam); } if(pivotIndex + 1 < param.get("endIndex")){ Map<String, Integer> rightParam = new HashMap<String, Integer>(); rightParam.put("startIndex", pivotIndex + 1); rightParam.put("endIndex", param.get("endIndex")); quickSortStack.push(rightParam); } } } /** * 分治(单边循环法) * @param arr 待交换的数组 * @param startIndex 起始下标 * @param endIndex 结束下标 */ private static int partition(int[] arr, int startIndex, int endIndex) { // 取第一个位置的元素作为基准元素(也可以选择随机位置) int pivot = arr[startIndex]; int mark = startIndex; for(int i=startIndex+1; i<=endIndex; i++){ if(arr[i]<pivot){ mark ++; int p = arr[mark]; arr[mark] = arr[i]; arr[i] = p; } } arr[startIndex] = arr[mark]; arr[mark] = pivot; return mark; } public static void main(String[] args) { int[] arr = new int[] {4,7,6,5,3,2,8,1}; quickSort(arr, 0, arr.length-1); System.out.println(Arrays.toString(arr)); } }
堆排序
import java.util.Arrays; public class HeapSort { /** * 下沉调整 * @param array 待调整的堆 * @param parentIndex 要下沉的父节点 * @param length 堆的有效大小 */ public static void downAdjust(int[] array, int parentIndex, int length) { // temp保存父节点值,用于最后的赋值 int temp = array[parentIndex]; int childIndex = 2 * parentIndex + 1; while (childIndex < length) { // 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子 if (childIndex + 1 < length && array[childIndex + 1] > array[childIndex]) { childIndex++; } // 如果父节点大于等于任何一个孩子的值,直接跳出 if (temp >= array[childIndex]) break; //无需真正交换,单向赋值即可 array[parentIndex] = array[childIndex]; parentIndex = childIndex; childIndex = 2 * childIndex + 1; } array[parentIndex] = temp; } /** * 堆排序(升序) * @param array 待调整的堆 */ public static void heapSort(int[] array) { // 1.把无序数组构建成最大堆。 for (int i = (array.length-2)/2; i >= 0; i--) { downAdjust(array, i, array.length); } System.out.println(Arrays.toString(array)); // 2.循环交换集合尾部元素到堆顶,并调节堆产生新的堆顶。 for (int i = array.length - 1; i > 0; i--) { // 最后一个元素和第一元素进行交换 int temp = array[i]; array[i] = array[0]; array[0] = temp; // 下沉调整最大堆 downAdjust(array, 0, i); } } public static void main(String[] args) { int[] arr = new int[] {1,3,2,6,5,7,8,9,10,0}; heapSort(arr); System.out.println(Arrays.toString(arr)); } }
桶排序
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; public class BucketSort { public static double[] bucketSort(double[] array){ //1.得到数列的最大值和最小值,并算出差值d double max = array[0]; double min = array[0]; for(int i=1; i<array.length; i++) { if(array[i] > max) { max = array[i]; } if(array[i] < min) { min = array[i]; } } double d = max - min; //2.初始化桶 int bucketNum = array.length; ArrayList<LinkedList<Double>> bucketList = new ArrayList<LinkedList<Double>>(bucketNum); for(int i = 0; i < bucketNum; i++){ bucketList.add(new LinkedList<Double>()); } //3.遍历原始数组,将每个元素放入桶中 for(int i = 0; i < array.length; i++){ int num = (int)((array[i] - min) * (bucketNum-1) / d); bucketList.get(num).add(array[i]); } //4.对每个桶内部进行排序 for(int i = 0; i < bucketList.size(); i++){ //JDK底层采用了归并排序或归并的优化版本 Collections.sort(bucketList.get(i)); } //5.输出全部元素 double[] sortedArray = new double[array.length]; int index = 0; for(LinkedList<Double> list : bucketList){ for(double element : list){ sortedArray[index] = element; index++; } } return sortedArray; } public static void main(String[] args) { double[] array = new double[] {4.12,6.421,0.0023,3.0,2.123,8.122,4.12, 10.09}; double[] sortedArray = bucketSort(array); System.out.println(Arrays.toString(sortedArray)); } }
计数排序
import java.util.Arrays; public class CountSort { public static int[] countSort(int[] array) { //1.得到数列的最大值 int max = array[0]; for(int i=1; i<array.length; i++){ if(array[i] > max){ max = array[i]; } } //2.根据数列最大值确定统计数组的长度 int[] countArray = new int[max+1]; //3.遍历数列,填充统计数组 for(int i=0; i<array.length; i++){ countArray[array[i]]++; } //4.遍历统计数组,输出结果 int index = 0; int[] sortedArray = new int[array.length]; for(int i=0; i<countArray.length; i++){ for(int j=0; j<countArray[i]; j++){ sortedArray[index++] = i; } } return sortedArray; } public static int[] countSortV2(int[] array) { //1.得到数列的最大值和最小值,并算出差值d int max = array[0]; int min = array[0]; for(int i=1; i<array.length; i++) { if(array[i] > max) { max = array[i]; } if(array[i] < min) { min = array[i]; } } int d = max - min; //2.创建统计数组并统计对应元素个数 int[] countArray = new int[d+1]; for(int i=0; i<array.length; i++) { countArray[array[i]-min]++; } //3.统计数组做变形,后面的元素等于前面的元素之和 for(int i=1;i<countArray.length;i++) { countArray[i] += countArray[i-1]; } //4.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组 int[] sortedArray = new int[array.length]; for(int i=array.length-1;i>=0;i--) { sortedArray[countArray[array[i]-min]-1]=array[i]; countArray[array[i]-min]--; } return sortedArray; } public static void main(String[] args) { int[] array = new int[] {4,4,6,5,3,2,8,1,7,5,6,0,10}; int[] sortedArray = countSort(array); System.out.println(Arrays.toString(sortedArray)); array = new int[] {95,94,91,98,99,90,99,93,91,92}; sortedArray = countSort(array); System.out.println(Arrays.toString(sortedArray)); } }