Java常用的八種排序算法與代碼實現

目錄:

1.直接插入排序

2.希爾排序

3.簡單選擇排序

4.堆排序

5.冒泡排序

6.快速排序

7.歸併排序

8.基數排序


1.直接插入排序

經常碰到這樣一類排序問題:把新的數據插入到已經排好的數據列中。

將第一個數和第二個數排序,然後構成一個有序序列

將第三個數插入進去,構成一個新的有序序列。

對第四個數、第五個數……直到最後一個數,重複第二步。


如何寫成代碼:

首先設定插入次數,即循環次數,for(int i=1;i<length;i++),1個數的那次不用插入。

設定插入數和得到已經排好序列的最後一個數的位數。insertNum和j=i-1。

從最後一個數開始向前循環,如果插入數小於當前數,就將當前數向後移動一位。

將當前數放置到空着的位置,即j+1。

代碼實現如下:




2.希爾排序

對於直接插入排序問題,數據量巨大時。

將數的個數設爲n,取奇數k=n/2,將下標差值爲k的書分爲一組,構成有序序列。

再取k=k/2 ,將下標差值爲k的書分爲一組,構成有序序列。

重複第二步,直到k=1執行簡單插入排序。



如何寫成代碼:

首先確定分的組數。

然後對組中元素進行插入排序。

然後將length/2,重複1,2步,直到length=0爲止。

代碼實現如下:



3.簡單選擇排序

常用於取序列中最大最小的幾個數時。

(如果每次比較都交換,那麼就是交換排序;如果每次比較完一個循環再交換,就是簡單選擇排序。)

遍歷整個序列,將最小的數放在最前面。

遍歷剩下的序列,將最小的數放在最前面。

重複第二步,直到只剩下一個數。


如何寫成代碼:

首先確定循環次數,並且記住當前數字和當前位置。

將當前位置後面所有的數與當前數字進行對比,小數賦值給key,並記住小數的位置。

比對完成後,將最小的值與第一個數的值交換。

重複2、3步。


代碼實現如下:



4.堆排序

對簡單選擇排序的優化。

將序列構建成大頂堆。

將根節點與最後一個節點交換,然後斷開最後一個節點。

重複第一、二步,直到所有節點斷開。



代碼實現如下

  1. public  void heapSort(int[] a){

  2.        System.out.println("開始排序");

  3.        int arrayLength=a.length;

  4.        //循環建堆  

  5.        for(int i=0;i<arrayLength-1;i++){

  6.            //建堆  


  7.            buildMaxHeap(a,arrayLength-1-i);

  8.            //交換堆頂和最後一個元素  

  9.            swap(a,0,arrayLength-1-i);

  10.            System.out.println(Arrays.toString(a));

  11.        }

  12.    }

  13.    private  void swap(int[] data, int i, int j) {

  14.        // TODO Auto-generated method stub  

  15.        int tmp=data[i];

  16.        data[i]=data[j];

  17.        data[j]=tmp;

  18.    }

  19.    //對data數組從0到lastIndex建大頂堆  

  20.    private void buildMaxHeap(int[] data, int lastIndex) {

  21.        // TODO Auto-generated method stub  

  22.        //從lastIndex處節點(最後一個節點)的父節點開始  

  23.        for(int i=(lastIndex-1)/2;i>=0;i--){

  24.            //k保存正在判斷的節點  

  25.            int k=i;

  26.            //如果當前k節點的子節點存在  

  27.            while(k*2+1<=lastIndex){

  28.                //k節點的左子節點的索引  

  29.                int biggerIndex=2*k+1;

  30.                //如果biggerIndex小於lastIndex,即biggerIndex+1代表的k節點的右子節點存在  

  31.                if(biggerIndex<lastIndex){

  32.                    //若果右子節點的值較大  

  33.                    if(data[biggerIndex]<data[biggerIndex+1]){

  34.                        //biggerIndex總是記錄較大子節點的索引  

  35.                        biggerIndex++;

  36.                    }

  37.                }

  38.                //如果k節點的值小於其較大的子節點的值  

  39.                if(data[k]<data[biggerIndex]){

  40.                    //交換他們  

  41.                    swap(data,k,biggerIndex);

  42.               //將biggerIndex賦予k,開始while循環的下一次循環,重新保證k節點的值大於其左右子節點的值  

  43.                    k=biggerIndex;

  44.                }else{

  45.                    break;

  46.                }

  47.            }

  48.        }

  49.    }

5.冒泡排序

一般不用。

將序列中所有元素兩兩比較,將最大的放在最後面。

將剩餘序列中所有元素兩兩比較,將最大的放在最後面。

重複第二步,直到只剩下一個數。


如何寫成代碼:

設置循環次數。

設置開始比較的位數,和結束的位數。

兩兩比較,將最小的放到前面去。

重複2、3步,直到循環次數完畢。

代碼實現如下:




6.快速排序

要求時間最快時。

選擇第一個數爲p,小於p的數放在左邊,大於p的數放在右邊。

遞歸的將p左邊和右邊的數都按照第一步進行,直到不能遞歸。



代碼實現如下:




7.歸併排序


速度僅次於快排,內存少的時候使用,可以進行並行計算的時候使用。

選擇相鄰兩個數組成一個有序序列。

選擇相鄰的兩個有序序列組成一個有序序列。

重複第二步,直到全部組成一個有序序列。



代碼實現如下:

  1. public static void mergeSort(int[] numbers, int left, int right) {  

  2.    int t = 1;// 每組元素個數  

  3.    int size = right - left + 1;  

  4.    while (< size) {  

  5.        int s = t;// 本次循環每組元素個數  

  6.        t = 2 * s;  

  7.        int i = left;  

  8.        while (+ (- 1) < size) {  

  9.            merge(numbers, i, i + (- 1), i + (- 1));  

  10.            i += t;  

  11.        }  

  12.        if (+ (- 1) < right)  

  13.            merge(numbers, i, i + (- 1), right);  

  14.    }  

  15. }  

  16. private static void merge(int[] data, int p, int q, int r) {  

  17.    int[] B = new int[data.length];  

  18.    int s = p;  

  19.    int t = q + 1;  

  20.    int k = p;  

  21.    while (<= q && t <= r) {  

  22.        if (data[s] <= data[t]) {  

  23.            B[k] = data[s];  

  24.            s++;  

  25.        } else {  

  26.            B[k] = data[t];  

  27.            t++;  

  28.        }  

  29.        k++;  

  30.    }  

  31.    if (== q + 1)  

  32.        B[k++] = data[t++];  

  33.    else  

  34.        B[k++] = data[s++];  

  35.    for (int i = p; i <= r; i++)  

  36.        data[i] = B[i];  

  37. }



8.基數排序

用於大量數,很長的數進行排序時。

將所有的數的個位數取出,按照個位數進行排序,構成一個序列。

將新構成的所有的數的十位數取出,按照十位數進行排序,構成一個序列。



代碼實現如下:


  1. public void sort(int[] array) {

  2.        //首先確定排序的趟數;    

  3.        int max = array[0];

  4.        for (int i = 1; i < array.length; i++) {

  5.            if (array[i] > max) {

  6.                max = array[i];

  7.            }

  8.        }

  9.        int time = 0;

  10.        //判斷位數;    

  11.        while (max > 0) {

  12.            max /= 10;

  13.            time++;

  14.        }

  15.        //建立10個隊列;    

  16.        List<ArrayList> queue = new ArrayList<ArrayList>();

  17.        for (int i = 0; i < 10; i++) {

  18.            ArrayList<Integer> queue1 = new ArrayList<Integer>();

  19.            queue.add(queue1);

  20.        }

  21.        //進行time次分配和收集;    

  22.        for (int i = 0; i < time; i++) {

  23.            //分配數組元素;    

  24.            for (int j = 0; j < array.length; j++) {

  25.                //得到數字的第time+1位數;  

  26.                int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);

  27.                ArrayList<Integer> queue2 = queue.get(x);

  28.                queue2.add(array[j]);

  29.                queue.set(x, queue2);

  30.            }

  31.            int count = 0;//元素計數器;    

  32.            //收集隊列元素;    

  33.            for (int k = 0; k < 10; k++) {

  34.                while (queue.get(k).size() > 0) {

  35.                    ArrayList<Integer> queue3 = queue.get(k);

  36.                    array[count] = queue3.get(0);

  37.                    queue3.remove(0);

  38.                    count++;

  39.                }

  40.            }

  41.        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章