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 }
View Code

相关文章: