本文共 12578 字,大约阅读时间需要 41 分钟。
十大排序算法脑图:
public static void sort(int array[]) { for (int i = 0; i < array.length - 1; i++) { for (int j = 0; j < array.length - i - 1; j++) { int temp = 0; if (array[j] > array[j + 1]) { temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } if (isSorted){ break; } }}
问题:经过多轮排序后,数列已经有序了,剩下的几轮排序就不必执行了,可以提前结束
解决:判断数列是否已经有序,并做出标记 如果本轮排序中有元素交换,则说明数列无序,如果没有元素交换,则说明数列已经有序,直接跳出大循环。public static void sort(int array[]) { for (int i = 0; i < array.length - 1; i++) { //有序标记,每一轮的初始值都是true boolean isSorted = true; for (int j = 0; j < array.length - i - 1; j++) { int temp = 0; if (array[j] > array[j + 1]) { temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; //因为有元素进行交换,所以不是有序的,标记变为false isSorted = false; } } if (isSorted){ break; } }}
问题:后半部分元素中的最小值大于前半部分元素的最大值,即右边的许多元素已经有序了
解决:对数列有序区的界定 每一轮排序后,记录下来最后一次元素交换的位置,该位置即为无序数列的边界,再往后就是有序区了public static void sort_2(int array[]) { for (int i = 0; i < array.length - 1; i++) { //有序标记,每一轮的初始值都是true boolean isSorted = true; //无序数列的边界,每次比较只需要比到这里为止 int sortBorder = array.length -1; for (int j = 0; j < sortBorder; j++) { int temp = 0; if (array[j] > array[j + 1]) { temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; //因为有元素进行交换,所以不是有序的,标记变为false isSorted = false; //把无序数列的边界更新为最后一次交换元素位置 sortBorder = j; } } if (isSorted){ break; } }}
参考链接:
参考链接:
public class select_sort { public static void selctionSort(int[] arr){ if (arr == null || arr.length < 2){ return; } for (int i = 0; i < arr.length; i++) { int minIndex = i; for (int j = i + 1; j < arr.length; j++) { minIndex = arr[j] < arr[minIndex] ? j : minIndex; } swap(arr,i,minIndex); } } public static void swap(int[] arr,int i,int j){ /* arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j];*/ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }}
/** * 插入排序 * 一堆有序的扑克牌,插入一张牌 */public class Insert_Sort { public static void insertionSort(int[] arr){ if (arr == null || arr.length < 2){ return; } for (int i = 1; i < arr.length; i++) { for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { swap(arr,j,j+1); } } } public static void swap(int[] arr,int i,int j){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }}
在这里插入代码片
package sort;/** * Copyright (C), 2019-2020 * author candy_chen * date 2020/7/3 10:50 * version 1.0 * Description: 快速排序 * * partition() 分治法(双边循环法) * partitionV2() 分治法(单边循环法) */import java.util.Arrays;import java.util.HashMap;import java.util.Map;import java.util.Stack;/** * */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); } /** * 非递归实现快排 * 转换成栈的实现,在栈中存储每一次方法调用的参数 * 该方法引入一个存储Map类型元素的栈,用于存储每一次交换时的起始下标和结束下标 * 每一次循环,都会让栈顶元素出栈,通过partition方法进行分治,并且按照基准元素的位置分成左右两部分,左右两部分再分别入栈。 * 当栈位空时,说明排序完毕,退出循环。 */ public static void quickSort_(int[] arr,int startIndex,int endIndex){ //用一个集合栈来代替递归的函数栈 Stack
在这里插入代码片
参考链接:
package basic_class_01;import java.util.Arrays;public class Code_05_MergeSort { public static void mergeSort(int[] arr) { if (arr == null || arr.length < 2) { return; } mergeSort(arr, 0, arr.length - 1); } public static void mergeSort(int[] arr, int l, int r) { if (l == r) { return; } int mid = l + ((r - l) >> 1); mergeSort(arr, l, mid); mergeSort(arr, mid + 1, r); merge(arr, l, mid, r); } public static void merge(int[] arr, int l, int m, int r) { int[] help = new int[r - l + 1]; int i = 0; int p1 = l; int p2 = m + 1; while (p1 <= m && p2 <= r) { help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; } while (p1 <= m) { help[i++] = arr[p1++]; } while (p2 <= r) { help[i++] = arr[p2++]; } for (i = 0; i < help.length; i++) { arr[l + i] = help[i]; } } // for test public static void comparator(int[] arr) { Arrays.sort(arr); } // for test public static int[] generateRandomArray(int maxSize, int maxValue) { int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; for (int i = 0; i < arr.length; i++) { arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); } return arr; } // for test public static int[] copyArray(int[] arr) { if (arr == null) { return null; } int[] res = new int[arr.length]; for (int i = 0; i < arr.length; i++) { res[i] = arr[i]; } return res; } // for test public static boolean isEqual(int[] arr1, int[] arr2) { if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { return false; } if (arr1 == null && arr2 == null) { return true; } if (arr1.length != arr2.length) { return false; } for (int i = 0; i < arr1.length; i++) { if (arr1[i] != arr2[i]) { return false; } } return true; } // for test public static void printArray(int[] arr) { if (arr == null) { return; } for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } // for test public static void main(String[] args) { int testTime = 500000; int maxSize = 100; int maxValue = 100; boolean succeed = true; for (int i = 0; i < testTime; i++) { int[] arr1 = generateRandomArray(maxSize, maxValue); int[] arr2 = copyArray(arr1); mergeSort(arr1); comparator(arr2); if (!isEqual(arr1, arr2)) { succeed = false; printArray(arr1); printArray(arr2); break; } } System.out.println(succeed ? "Nice!" : "Fucking fucked!"); int[] arr = generateRandomArray(maxSize, maxValue); printArray(arr); mergeSort(arr); printArray(arr); }}
public class mergeSort { public static void mergeSort(int[] array,int left,int right){ if (right <= left) return; int mid = (left + right) >> 1;// (left + right) / 2 mergeSort(array, left, mid); mergeSort(array,mid + 1,right); merge(array,left,mid,right); } private static void merge(int[] arr, int left, int mid, int right) { int[] temp = new int[right - left + 1]; int i = left,j = mid + 1,k = 0; //两个数组要合并在一起的数组 while (i <= mid && j <= right){ temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++]; } while (i <= mid) temp[k++] = arr[i++]; while (j <= right) temp[k++] = arr[j++]; for (int p = 0; p < temp.length; p++) { arr[left + p] = temp[p]; } //也可以用System.arraycopy(a,start1,b,start2,length) }}
public class heapSort { static void heapify(int[] array,int length,int i){ int left = 2 * i + 1,right = 2 * i + 2; int largest = i; if (left < length && array[left] > array[largest]) { largest = left; } if (right < length && array[right] > array[largest]) { largest = right; } if (largest != i){ int temp = array[i]; array[i] = array[largest]; array[largest] = temp; heapify(array, length,largest); } } public static void heapSort(int[] array){ if (array.length == 0) return; int length = array.length; for (int i = length / 2 - 1;i >= 0; i--) { heapify(array,length,i); } for (int i = length - 1; i >= 0;i--){ int temp = array[0]; array[0] = array[i]; array[i] = temp; heapify(array,i,0); } }}
参考链接:
1.先得到数列的最大值;
2.根据数列最大值确定统计数组的长度,数组长度为:输入数列的最大值+1; 3.遍历数列,填充统计数组; 4. 遍历统计数组,输出结果public static int[] countSort(int[] array) { //1.得到数列的最大值 int max = array[0]; for (int i = 0; i < array.length; i++) { if (array[i] > max) { max = array[i]; } } //2.根据数列最大值确定统计数组的长度 int[] countArray = new int[array.length]; //3.遍历数列,填充统计数组 for (int i = 0; i < array.length; i++) { countArray[array[i]]++;//每一个整数按照其值对号入座,同时对应数组下标的元素进行加1操作 } //4.遍历统计数组,输出结果 int index = 0; int[] sortedArray = new int[array.length]; for (int i = 0; i < array.length; i++) { for (int j = 0; j < countArray[i]; j++) { sortedArray[index++] = i; } } return sortedArray;}
问题:最大数和最小数相差较小的时候,用最大值决定统计数组的长度容易浪费空间
解决:public static int[] countSort2(int[] array){ //1.得到数列的最大值和最小值,并计算出差值d int max = array[0]; int min = array[0]; for (int i=0;imax){ max = array[i]; } if (array[i] =0;i--){ /* * 先找到统计数组中下标为 * */ sortedArray[countArray[array[i] - min] -1] = array[i]; countArray[array[i] - min]--; } return sortedArray;}
参考链接:
桶排序:每一个桶代表的一个区间范围,可以承载一个或对个元素
桶的数量 桶的区间跨度package sort;/** * Copyright (C), 2019-2020 * author candy_chen * date 2020/7/13 19:03 * version 1.0 * Description: 测试 */import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.LinkedList;/** *桶排序 * 所有的桶都保存在ArrayList集合中,每一个桶都被定义成一个链表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 max){ max = array[i]; } if (array[i] > bucketList = new ArrayList >(bucketNum); for (int i = 0 ;i ()); } //3.遍历初始数组,将每个元素放入桶中 for (int i = 0;i linkedList: bucketList){ for (double element:linkedList) { sortedArray[index] = element; index++; } } return sortedArray; } public static void main(String[] args) { double[] array = new double[]{ 4.12,6.421,0.0023,2.123,8.122,4.12,10.09}; double[] sortedArray = bucketSort(array); System.out.println(Arrays.toString(sortedArray)); }}
参考链接:
在这里插入代码片
说明:根据网络资料进行搜索学习理解整理 若有侵权联系作者
转载地址:http://euer.baihongyu.com/