數據結構之排序算法

1、分類

1.1 內部排序

1、插入排序算法

  1.直接插入排序數組

  2.折半插入排序數據結構

  3.希爾排序spa

2、交換類排序.net

  1.冒泡排序3d

  2.快速排序blog

3、選擇類排序排序

  1.簡單選擇排序 索引

  2.堆排序內存

4、歸併排序

  二路歸併排序

1.2 外部排序

  歸併排序

2、各排序詳解

直接插入排序

public static void insertionSort(int[] a) {

        int tmp;

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

            for (int j = i; j > 0; j--) {

                if (a[j] < a[j - 1]) {

                    tmp = a[j - 1];

                    a[j - 1] = a[j];

                    a[j] = tmp;

                }

            }

        }

}

折半插入排序

尋找插入的位置採用折半查找法

希爾排序

希爾(Shell)排序又稱爲縮小增量排序,它是一種插入排序。它是直接插入排序算法的一種威力增強版。

把記錄按步長 gap 分組,對每組記錄採用直接插入排序方法進行排序。隨着步長逐漸減少,所分紅的組包含的記錄愈來愈多,當步長的值減少到 1 時,整個數據合成爲一組,構成一組有序記錄,則完成排序。gap1 = N / 2  gapk = gap(k-1) / 2

 

 

冒泡排序

public static void bubbleSort(int[] a) {

        int flag;

     int temp;

        for (int i = a.length-1; i > 0; --i) {

      flag = 0;

             for (int j = 1; j <= i; ++j) {

                if (a[j] < a[j - 1]) {

                     temp = a[j];

                     a[j] = a[j - 1];

                     a[j - 1] = temp;

        flag = 1;

                }

            }

     if(flag == 0)

        return;

          } 

}

快速排序

public static void partition(int []array,int lo,int hi){

        //固定的切分方式

        int key=array[lo];

        while(lo<hi){

            while(array[hi]>=key&&hi>lo){ 

                hi--;

            }

            array[lo]=array[hi];

            while(array[lo]<=key&&hi>lo){ 

                lo++;

            }

            array[hi]=array[lo];

        }

        array[hi]=key;

        partition(int []array,lo, hi-1);

    partition(int []array, lo, hi+1);

}

簡單選擇排序

public void selectionSort(int[] list) {
     // 須要遍歷得到最小值的次數
     // 要注意一點,當要排序 N 個數,已經通過 N-1 次遍歷後,已是有序數列
     for (int i = 0; i < list.length - 1; i++) {
         int temp = 0;
         int index = i; // 用來保存最小值得索引 
         // 尋找第i個小的數值
         for (int j = i + 1; j < list.length; j++) {
               if (list[index] > list[j]) {
                   index = j;
               }

       temp = list[index];
           list[index] = list[i];
              list[i] = temp; 
              printAll(list);

     } 

堆排序

先將初始文件R[1..n]建成一個大根堆,此堆爲初始的無序區

再將關鍵字最大的記錄R[1](即堆頂)和無序區的最後一個記錄R[n]交換,由此獲得新的無序區R[1..n-1]和有序區R[n],且知足R[1..n-1].keys≤R[n].key

因爲交換後新的根R[1]可能違反堆性質,故應將當前無序區R[1..n-1]調整爲堆。而後再次將R[1..n-1]中關鍵字最大的記錄R[1]和該區間的最後一個記錄R[n-1]交換,由此獲得新的無序區R[1..n-2]和有序區R[n-1..n],且仍知足關係R[1..n-2].keys≤R[n-1..n].keys,一樣要將R[1..n-2]調整爲堆。

……

直到無序區只有一個元素爲止。

 

public class HeapSort {

    /**

     * 構建大頂堆  數組下標從1開始

     */

    public static void adjustHeap(int[] a, int i, int len) {

        int temp, j;

        temp = a[i];

        for (j = 2 * i; j <= len; j *= 2) {// 沿關鍵字較大的孩子結點向下篩選

            if (j < len && a[j] < a[j + 1])

                ++j; // j爲關鍵字中較大記錄的下標

            if (temp >= a[j])

                break;

            a[i] = a[j];

            i = j;

        }

        a[i] = temp;

    }

 

    public static void heapSort(int[] a) {

        int i;

        for (i = a.length / 2; i > 0; i--) {// 構建一個大頂堆

            adjustHeap(a, i, a.length);

        }

        for (i = a.length; i > 1; i--) {// 將堆頂記錄和當前未經排序子序列的最後一個記錄交換

            int temp = a[1];

            a[1] = a[i];

            a[i] = temp;

            adjustHeap(a, 1, i - 1);// a中前i-1個記錄從新調整爲大頂堆

        }

    }

 

    public static void main(String[] args) {

        int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };

        heapSort(a);

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

    }

}

二路歸併排序(內部)

 

K路歸併排序(外部)

外部排序指的是大文件的排序,即待排序的記錄存儲在外存儲器上,待排序的文件沒法一次裝入內存,須要在內存和外部存儲器之間進行屢次數據交換,以達到排序整個文件的目的。外部排序最經常使用的算法是多路歸併排序,即將原文件分解成多個可以一次性裝內存的部分,分別把每一部分調入內存完成排序。而後,對已經排序的子文件進行歸併排序。

過程 :

1.初始歸併段生成

  將文件分段輸入內存並排序,排序完的文件稱歸併段,將其寫入外存,這樣就造成了許多初始歸併段。

置換-選擇排序

  文件輸入記錄,當填滿緩衝區後,選擇最小記錄輸出,空缺位置由下個輸入記錄取代,輸出記錄即爲初始歸併段的一部分。(新填充的記錄若是不能成爲當前歸併段的一部分,也就是說比當前歸併段最大記錄小,那麼等待下一個歸併段提供選擇)

2.最佳歸併樹創建

二路歸併即用哈夫曼樹,I/O次數 = 帶權路徑長度*2

3、複雜度與穩定性

3.1 時間複雜度

平均狀況

  快速排序、希爾排序、堆排序、歸併排序 O(log2n)

  其餘的爲On平方)

最壞狀況

  快排爲On平方),越無序越好

  其餘和平均狀況同樣

最好狀況

  有序的狀況下,直接插入排序和冒泡排序爲On

3.2 空間複雜度

  快排爲Olog2n

  歸併排序爲On

3.3 穩定性

  快速排序、希爾排序、簡單選擇排序、堆排序爲不穩定的

  其他爲穩定的

相關文章
相關標籤/搜索