180813 补全没有的答案!
0、 数组排序大全[冒泡/选择/快速/插入]
1 package com.ftl; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.util.ArrayList; 7 import java.util.Arrays; 8 import java.util.Collections; 9 import java.util.Iterator; 10 import java.util.List; 11 12 /** 13 * 排序算法复习 14 * @author 小a玖拾柒 15 * Date: 2018年8月18日 16 * 【更多参考】 https://blog.csdn.net/snow_5288/article/details/60140265 17 */ 18 19 public class Test2018 { 20 21 public static void main(String[] args) throws IOException { 22 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 23 List<Double> l = null; 24 System.out.println("[eg.]请输入数据,如:1,12,32,2,3"); 25 String input = br.readLine(); 26 //方案一: 多数排序 27 check(input); 28 //方案二: 冒泡排序 29 check2(input); 30 //方案三: 快速选择排序 31 check3(input); 32 //方案四: 插入排序 33 check4(input); 34 //方案五: 快速排序 35 check5(input); 36 } 37 38 //方案一: list排序:利用Collections工具类实现 39 public static void check(String str){ 40 String[] s = str.split(","); 41 int[] ch = new int[s.length]; 42 List<Integer> list = new ArrayList<Integer>(); 43 for(int i = 0; i < s.length; i++){ 44 ch[i] = Integer.parseInt(s[i]); 45 list.add(ch[i]); 46 } 47 Collections.sort(list); 48 System.out.println("【方案一】list排序 :" + list); 49 50 } 51 //方案二: 冒泡排序: 相邻2个数字比较,一次排序后最大/最小的数字排列最后 52 /** 53 * 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 54 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。 55 针对所有的元素重复以上的步骤,除了最后一个。 56 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 57 冒泡排序需要n-1(i)趟冒泡,每趟冒泡需要比较n-1-i(j)次比较,总共的比较次数为(n-1)+(n-2)+……+1, 58 所以冒泡排序算法最坏情况和平均复杂度是O(n²)。 59 由于占用空间有限,冒泡排序的空间复杂度为O(1)。 60 */ 61 public static void check2(String str){ 62 String[] s = str.split(","); 63 int[] ch = new int[s.length]; 64 for(int i = 0; i < s.length; i++){ 65 ch[i] = Integer.parseInt(s[i]); 66 } 67 for(int i = 1; i < ch.length; i++){ 68 for(int j = 0; j < ch.length; j++){ 69 if(ch[i] < ch[j]){ 70 int tmp = ch[i]; 71 ch[i] = ch[j]; 72 ch[j] = tmp; 73 } 74 } 75 } 76 System.out.println("【方案二】冒泡排序后:" + Arrays.toString(ch)); 77 } 78 //方案三: 快速选择排序: 第一个数字依次跟后面的数字比较大小 79 /** 80 * 是直观的排序,通过确定一个Key最大或最小值,再从带排序的的数中找出最大或最小的交换到对应位置。再选择次之 81 * 双重循环时间复杂度为O(n^2) 82 */ 83 public static void check3(String str){ 84 String[] s = str.split(","); 85 int[] ch = new int[s.length]; 86 for(int i = 0; i < s.length; i++){ 87 ch[i] = Integer.parseInt(s[i]); 88 } 89 for(int i = 0; i < ch.length; i++){ 90 for(int j = i+1; j < ch.length ; j++){ 91 if(ch[i] > ch[j]){ 92 int tmp = ch[i]; 93 ch[i] = ch[j]; 94 ch[j] = tmp; 95 } 96 } 97 } 98 System.out.println("【方案三】选择排序后:" + Arrays.toString(ch)); 99 } 100 //方案四: 插入排序:往前比较,如果当前数比前一个小则进行第二个循环操作,反之则直接进入下次外层循环 101 //比冒泡更优秀一点,冒泡是无论大小都会继续比较,这里是如果当前数字比前面的小,交换位置[降序则反之即可] 102 public static void check4(String str){ 103 String[] s = str.split(","); 104 int[] ch = new int[s.length]; 105 for(int i = 0; i < s.length; i++){ 106 ch[i] = Integer.parseInt(s[i]); 107 } 108 for(int i = 1; i < ch.length; i++){ 109 int tmp = ch[i]; 110 // 升序: 如果前面的数字比当前的tmp大,则交换位置 111 for(int j = i - 1; j >=0 && tmp < ch[j]; j--){ 112 ch[j+1] = ch[j]; 113 ch[j] = tmp; 114 } 115 } 116 System.out.println("【方案四】插入排序后:" + Arrays.toString(ch)); 117 } 118 //方案五:快速排序:选择一个基准,大于该值放在右侧,小于则放在左侧 119 /** 120 * 选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。 121 一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。 122 接着分别比较左右两边的序列,重复上述的循环。 123 快速排序是一种快速的分而治之的算法,它是已知的最快的排序算法,其平均运行时间为O(N*1ogN) 。它的速度主要归功于一个非长紧凑的并且高度优化的内部循环。但是他也是一种不稳定的排序,当基准数选择的不合理的时候他的效率又会编程O(N*N)。 124 快速排序的最好情况: 快速排序的最好情况是每次都划分后左右子序列的大小都相等,其运行的时间就为O(N*1ogN)。 125 快速排序的最坏情况: 快速排序的最坏的情况就是当分组重复生成一个空序列的时候,这时候其运行时间就变为O(N*N) 126 快速排序的时间复杂度为O(N*lgN),快速排序的空间复杂度为O(lgN). 127 */ 128 public static void check5(String str){ 129 String[] s = str.split(","); 130 int[] ch = new int[s.length]; 131 for(int i = 0; i < s.length; i++){ 132 ch[i] = Integer.parseInt(s[i]); 133 } 134 if(ch.length <=1) return ; 135 int start = 0; 136 int end = ch.length-1; 137 check5sort(ch, start, end); 138 System.out.println("【方案五】快速排序后:" + Arrays.toString(ch)); 139 } 140 141 public static void check5sort(int[] a,int low,int high){ 142 int start = low; 143 int end = high; 144 int key = a[low]; // 设定基准为第一个数字 145 146 147 while(end>start){ 148 //从后往前比较 149 while(end>start&&a[end]>=key) //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较 150 end--; 151 if(a[end]<=key){ 152 int temp = a[end]; 153 a[end] = a[start]; 154 a[start] = temp; 155 } 156 //从前往后比较 157 while(end>start&&a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置 158 start++; 159 if(a[start]>=key){ 160 int temp = a[start]; 161 a[start] = a[end]; 162 a[end] = temp; 163 } 164 //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用 165 } 166 //递归 167 if(start>low) check5sort(a,low,start-1); //左边序列。第一个索引位置到关键值索引-1 168 if(end<high) check5sort(a,end+1,high); //右边序列。从关键值索引+1到最后一个 169 } 170 }