快速排序,冒泡排序,选择排序比较

 快速排序,冒泡排序,选择排序是比较基础的排序方法,我通过随机生成一个大小1000的数组,然后使用内部类创建线程来比较耗费时间

   首先快速排序算法:
        快速排序算法其实也叫分治法, 其步骤大致可以分为这么几步:
  1. 先从数列中取出一个数作为基准数Num(取得好的话, 是可以减少步骤的)
  2. 分区, 将大于Num的数放在它的右边, 小于或等于它的数放在它的左边
  3. 再对左右区间重复前两操作, 直到各个区间只有一个数为止.

  这里是使用递归方式创建的快速排序

   

 1 public static void kspxSort(int[] a,int low, int hight) {
 2         int start=low;
 3         int end=hight;
 4         int key=a[low];
 5         while(end>start) {
 6             //从end开始和key比较
 7              while(end>start&&a[end]>=key) {
 8                  end--;
 9              }
10             if(a[end]<=key) {
11                 int temp = a[end];
12                 a[end] = a[start];
13                 a[start] = temp;                    
14             }
15              while(end>start&&a[start]<=key) {
16                  start++;
17                  
18              }
19             if(a[start]>=key) {
20                 int temp = a[start];
21                 a[start]=a[end];
22                 a[end]=temp;
23             }
24             
25             
26         }
27         
28         //递归调用
29          if(start>low) {kspxSort(a,low,start-1);}
30          if(end<hight) {kspxSort(a,end+1,hight);}
31         
32     }

 然后是冒泡排序

    将要排序的一组数字进行遍历。
第一次遍历,将相邻的两个数字进行比较,直到这组数字全部比较完成,如果前面比后面的数字大,则进行交换位置,此时可以将最大的数字筛选出来,放到最后的位置上。
第二次遍历,将相邻的两个数字进行比较,直到这组数字全部比较完成,如果前面比后面的数字大,则进行交换位置,将这组数字里面第二大的数字筛选出来,放到倒数第二的位置上。
依次进行遍历,交换位置,直到排序完成。

 1     public static void bubbleSort(int[] a) {
 2         int n = a.length;
 3         int temp;
 4         for(int i=0;i<n-1;i++) {
 5             
 6             for(int j=0;j<n-1-i;j++) {
 7                 
 8                 if(a[j]>a[j+1]) {
 9                     temp = a[j];
10                     a[j] =a[j+1];
11                     a[j+1] = temp;
12                 }
13             }
14         }        
15     }

然后是选择排序

   将要排序的一组数字进行遍历。
第一次遍历,将第一个位置上的数字与后面的数字进行比较,如果后面的数字比第一个位置上的元素小,则将两个数字的位置进行交换。
第二次遍历,将第二个位置上的数字与后面的数字进行比较,如果后面的数字比第二个位置上的元素小,则将两个数字的位置进行交换。
依次进行遍历、位置交换,直到这组数字排序完成。

 1 public static void selectSort(int[] a) {
 2          for(int i=0;i<a.length-1;i++){
 3 
 4                 //假设第一个数据是最小值
 5                 //记录最小值元素的下标
 6                 int min = i;
 7 
 8                 for(int j=i+1;j<a.length;j++){
 9 
10                     if(a[min]>a[j]){
11                         //给min重新赋值
12                         min = j;
13                     }
14                 }
15 
16                 //交换位置
17                 if(min != i){
18                     int temp;
19                     temp = a[i];
20                     a[i] = a[min];
21                     a[min] = temp;
22                 }
23 
24             }
25     }

 

然后再main方法主线程中中创建一个随机数组,大小100000;读者可以创建更大以便获得更好的效果;

1  int[] arry= new int[100000];    
2         for(int i=0;i<100000;i++) {
3             arry[i]= (int)(Math.random()*100000);
4         }

     使用多线程调用

 

 1   new Thread() { // 1.继承Thread类
 2                 public void run() { // 2.重写run方法
 3                   long t1 = new Date().getTime();
 4                      kspxSort(arry, 0, arry.length-1);
 5                      long t2 = new Date().getTime();
 6                      System.out.println("快速排序消耗时间:"+(t2-t1));
 7                 }
 8             }.start(); // 4.开启线程
 9         new Thread() {
10             public void run() {
11                 long t1 = new Date().getTime();
12                 bubbleSort(arry);
13                      long t2 = new Date().getTime();
14                      System.out.println("冒泡排序消耗时间:"+(t2-t1));
15             }
16         }.start();
17         new Thread() {
18             public void run() {
19                  long t1 = new Date().getTime();
20                  selectSort(arry);
21                      long t2 = new Date().getTime();
22                      System.out.println("选择排序消耗时间:"+(t2-t1));
23             }
24             
25         }.start();

 

结果如下:

快速排序消耗时间:33
选择排序消耗时间:2515
冒泡排序消耗时间:4227

相比较之下:快速排序最快,选择排序和冒泡排序相差不大,

在算法中用 0()函数 表示算法的时间效率与算法所处理的数据元素个数n函数关系的最常用函数是0()函数。
  定义:
  一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,

T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=0(f(n)),称0(f(n)) 为算法的渐进时间复杂度,简称时间复杂度

   对比三种算法,具体请看https://cloud.tencent.com/developer/article/1350860

   首先冒泡排序是基于比较和交换的,比如我们要对n个数字排序,冒泡排序需要n-1次遍历,比如我们有10个数字,第一趟循环需要比较9次,第二趟循环需要比较8次,第三趟需要比较7次,以此类推,最后一趟需要1次比较。

f(10)=9+8+7+......+1 ,可以转为一个等差数列:

f(n)=(n-1)+(n-2)+(n-3)+......+1= (n-1)*n / 2 = 0.5n^2-0.5n

当n趋于无穷大时否f(n)=n^2/2

 选择排序类似,但是最坏情况下,选则排序需要交换n-1次,冒泡排序需要交换n^2/2

快速排序

     快速排序的递推式为:T(n)=max(T(q) + T(n-q-1)) +O(n),q为切分长度,如果每次切分都刚好切分成两半,则 q==n-q-1, T(q)==T(n-q-1) ,则简化为 T(n)=2T(n/2)+O(n)。换一下加法项的位置,T(n)=O(n)+2T(n/2),若 快速排序每次都会以2为低做裂变分解数组,所以最终推出来的渐近复杂度:Ο(nlog2n)

    如内容有问题,恳请大佬们指出,小生定虚心接受,谢谢。

posted @ 2019-02-13 16:21  风眯了眼  阅读(4458)  评论(0编辑  收藏  举报