zoukankan      html  css  js  c++  java
  • 各种排序算法总结

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

    待排序的个数: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  总结

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

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

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

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

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

  • 相关阅读:
    CTF-cookies欺骗
    CTF-速度要快100
    php实现登录注册界面
    CTF-秋名山老司机 100
    三大类型语句
    PHP运算符
    标记风格和注释
    连接串口服务器时的注意事项
    RS485转以太网的概述和应用领域
    工业级路由器的优点有哪些
  • 原文地址:https://www.cnblogs.com/qijunhui/p/8445457.html
Copyright © 2011-2022 走看看