各种排序算法总结

本篇文章针对现有常用的排序算法进行比较,并计算出排序所用的时间。

待排序的个数:100000

待排序数值的范围:0~1000

1  简化版桶排序法

 1 import java.util.Random;
 2 
 3 /*对0~10000之间的100000个数从小到大排序
 4  * 简化桶排序法
 5  * 祁俊辉  17.5.2
 6  * */
 7 public class Tong {
 8     static int a[]=new int[100000];//定义存储100000个待排序数的数组
 9     static int b[]= new int[100001];//定义桶,范围0~100000,所以共10001个桶
10     //定义一个简易桶排序的方法
11     static void BarrelSort(int[] Dai,int[] Tou){//传入待排序数组、桶数组
12         for(int i=0;i<Dai.length;i++){
13             Tou[Dai[i]]++;
14         }
15     }
16     //生成随机数
17     static int RandomMM(int min,int max){
18         Random random = new Random();
19         int s = random.nextInt(max)%(max-min+1) + min;
20         return s;
21     }
22     //主方法
23     public static void main(String[] args) {
24         long starTime=System.currentTimeMillis();//当前时间赋给一个变量
25         for(int i=0;i<a.length;i++){
26             a[i] = RandomMM(0,10000);
27         }
28         BarrelSort(a,b);//桶排序调用
29         //输出排序后的结果
30         //遍历桶,为0的不打印(说明没出现过),1以上的循环打印(防止同一个数多次出现)
31         for(int i=0;i<b.length;i++){
32             for(int j=1;j<=b[i];j++){
33                 System.out.println(i);
34             }
35         }
36         long endTime=System.currentTimeMillis();//当前时间赋给一个变量
37         long time=endTime-starTime;//计算所用时间
38         System.out.println("对100000个“0~10000”范围的整数排序(冒泡排序法):"+time+"ms");//输出时间
39     }
40 }

2  冒泡排序法

 1 import java.util.Random;
 2 
 3 /*对0~10000之间的100000个数从小到大排序
 4  * 冒泡法
 5  * 祁俊辉  17.5.2
 6  * */
 7 public class Mao {
 8     static int a[]=new int[100000];//定义存储100000个待排序数的数组
 9     //定义一个冒泡排序的方法
10     static void BubbleSort(int[] Dai){
11         for(int i=1;i<Dai.length;i++){//n个数排序,只需进行n-1趟操作(一次操作只将1个数归位)
12             for(int j=0;j<Dai.length-i;j++){//第一趟比较n-1次,第二趟比较n-2次。。。
13                 if(Dai[j]>Dai[j+1]){//不满足条件,交换
14                     int temp=a[j];
15                     Dai[j]=Dai[j+1];
16                     Dai[j+1]=temp;
17                 }
18             }
19         }
20     }
21     //生成随机数
22     static int RandomMM(int min,int max){
23         Random random = new Random();
24         int s = random.nextInt(max)%(max-min+1) + min;
25         return s;
26     }
27     //主方法
28     public static void main(String[] args) {
29         long starTime=System.currentTimeMillis();//当前时间赋给一个变量
30         for(int i=0;i<a.length;i++){
31             a[i] = RandomMM(0,10000);
32         }
33         BubbleSort(a);//冒泡排序调用
34         //输出排序后的结果
35         for(int i=0;i<a.length;i++){
36             System.out.println(a[i]);
37         }
38         long endTime=System.currentTimeMillis();//当前时间赋给一个变量
39         long time=endTime-starTime;//计算所用时间
40         System.out.println("对100000个“0~10000”范围的整数排序(冒泡排序法):"+time+"ms");//输出时间
41     }
42 }

3  快速排序法

 1 import java.util.Random;
 2 
 3 /*对0~10000之间的100000个数从小到大排序
 4  * 快速排序法
 5  * 祁俊辉  17.5.2
 6  * */
 7 public class Kuai {
 8     static int a[]=new int[100000];//定义存储100000个待排序数的数组
 9     //定义一个快速排序的方法
10     static void QuickSort(int[] Dai,int left,int right){//传入待排序数组、左右下标
11         int i,j,t,temp;
12         if(left>right)//如果越界,则表示出错,直接退出
13             return;
14         temp=Dai[left];//存储基准数
15         i=left;
16         j=right;
17         while(i!=j){
18             while(Dai[j]>=temp && i<j)//注意顺序,先从右往左,要不然会落下一个数
19                 j--;
20             while(Dai[i]<=temp && i<j)//再从左往右
21                 i++;
22             if(i<j){//没有相遇,则交换
23                 t=Dai[i];
24                 Dai[i]=Dai[j];
25                 Dai[j]=t;
26             }
27         }
28         //运行到这里,说明左右相遇了,将基准数归位
29         Dai[left]=Dai[i];
30         Dai[i]=temp;
31         //左右递归运算
32         QuickSort(Dai,left,i-1);//继续处理左边的,递归
33         QuickSort(Dai,i+1,right);//继续处理右边的,递归
34     }
35     //生成随机数
36     static int RandomMM(int min,int max){
37         Random random = new Random();
38         int s = random.nextInt(max)%(max-min+1) + min;
39         return s;
40     }
41     //主方法
42     public static void main(String[] args) {
43         long starTime=System.currentTimeMillis();//当前时间赋给一个变量
44         for(int i=0;i<a.length;i++){
45             a[i] = RandomMM(0,10000);
46         }
47         QuickSort(a,0,a.length-1);//快速排序调用
48         //输出排序后的结果
49         for(int i=0;i<a.length;i++){
50             System.out.println(a[i]);
51         }
52         long endTime=System.currentTimeMillis();//当前时间赋给一个变量
53         long time=endTime-starTime;//计算所用时间
54         System.out.println("对100000个“0~10000”范围的整数排序(快速排序法):"+time+"ms");//输出时间
55     }
56 }

4  堆排序法(完全二叉树)

 1 import java.util.Random;
 2 
 3 /*对0~10000之间的100000个数从小到大排序
 4  * 堆排序法(堆:完全二叉树)
 5  * 祁俊辉  17.5.2
 6  * */
 7 public class Dui {
 8     static int a[]=new int[100001];//定义存储100000个待排序数的数组,下标从1~100000
 9     static int n=a.length-1;//待排序个数,也就是堆的大小
10     //交换函数,用来交换堆中两个元素的值
11     static void swap(int[]Dai,int x,int y){
12         int temp;
13         temp=Dai[x];
14         Dai[x]=Dai[y];
15         Dai[y]=temp;
16     }
17     //向下调整函数
18     static void siftdown(int[] Dai,int i){//传入待排数组和需要向下调整的下标
19         int t,flag=0;//flag用来标记是否需要继续向下调整
20         //当i结点有儿子(左)并且有需要继续调整的时候循环执行
21         while(i*2<=n && flag==0){
22             //首先判断左边,并用t记录值较小的结点编号
23             if(Dai[i] > Dai[i*2])
24                 t=i*2;
25             else
26                 t=i;
27             //如果它有左边,在对右边进行讨论
28             if(i*2+1 <= n){
29                 if(Dai[t] > Dai[i*2+1])
30                     t=i*2+1;
31             }
32             //如果发现最小的结点编号不是自己,说明子结点中有比父结点更小的
33             if(t!=i){
34                 swap(Dai,t,i);//交换它们
35                 i=t;//更新i
36             }else{
37                 flag=1;//否则说明当前父结点已经比它的子节点小,不需要进行调整
38             }
39         }
40     }
41     //建立堆的函数
42     static void creat(int[] Dai){
43         //从最后一个非页结点到第一个结点依次进行向下调整
44         for(int i=n/2;i>=1;i--)
45             siftdown(Dai,i);
46     }
47     //删除最大的元素
48     static int deletemax(int[] Dai){
49         int t=Dai[1];//用一个临时变量记录堆的顶点的值
50         Dai[1]=Dai[n];//将堆的最后一个点赋值到堆顶
51         n--;//堆的元素减1
52         siftdown(Dai,1);//向下调整
53         return t;//返回之前记录的堆的顶点的最大值
54     }    
55     //生成随机数
56     static int RandomMM(int min,int max){
57         Random random = new Random();
58         int s = random.nextInt(max)%(max-min+1) + min;
59         return s;
60     }
61     //主函数
62     public static void main(String[] args) {
63         long starTime=System.currentTimeMillis();//当前时间赋给一个变量
64         for(int i=0;i<a.length;i++){
65             a[i] = RandomMM(0,10000);
66         }
67         creat(a);//建堆
68         //删除顶部元素,连续删除n次,其实就是从小到大把数输出来
69         for(int i=1;i<=n;i++)
70             System.out.println(deletemax(a));
71         long endTime=System.currentTimeMillis();//当前时间赋给一个变量
72         long time=endTime-starTime;//计算所用时间
73         System.out.println("对100000个“0~10000”范围的整数排序(快速排序法):"+time+"ms");//输出时间
74     }
75 }

5  总结

以上只对四种排序方法进行比较,后期将持续更新。

简化版桶排序主要针对数值范围小、待排序个数多的数进行排序,因为数值范围直接影响它要设置多少个桶。

冒泡排序只是一种思想,在实际应用中不会应用,因为不管何种情况,效率太慢!

快速排序是一个值得推荐的排序方法。

堆排序法是从最小堆(完全二叉树)中扩展出来的,排序过程也是非常快速(也可以用最大堆进行排序,可以避免建立堆的过程,可能会更优化)。

posted @ 2018-02-12 20:23  祁俊辉  阅读(332)  评论(0)    收藏  举报