快速排序,冒泡排序,選擇排序比較


 快速排序,冒泡排序,選擇排序是比較基礎的排序方法,我通過隨機生成一個大小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)

    如內容有問題,懇請大佬們指出,小生定虛心接受,謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM