常用演算法之----選擇排序、插入排序和希爾排序

來源:互聯網
上載者:User

標籤:簡單的   shel   src   com   排序演算法   generated   複雜度   script   整合   

一些說明

我將會寫一系列關於演算法的部落格,因為我是程式員,並不是電腦科學家,也即我是搞工程的,並不是搞學術的,所以對於我來說,最重要的就是

1.有哪些演算法

2.這些演算法的原理

3.這些演算法的實現

4.這些演算法的效率

 

而其他的,相對而言,並沒有那麼重要,比如演算法的證明,所以以後的部落格都會按照上述的思維撰寫。

 

一、首先定義一個抽象類別,裡面整合了排序演算法所需要的共同的方法:

 

public abstract class SortBase {    public abstract Integer[] sort(Integer[] a);        public static void print(Integer[] arrayForSort) {        System.out.print("[");        for(int i=0;i<arrayForSort.length;i++) {            if(i == arrayForSort.length - 1) {                System.out.print(arrayForSort[i]);            } else {                System.out.print(arrayForSort[i] + " ,");            }        }        System.out.println("]");    }        public static void print(String prefix,Integer[] arrayForSort) {        System.out.print(prefix + ": ");        System.out.print("[");        for(int i=0;i<arrayForSort.length;i++) {            if(i == arrayForSort.length - 1) {                System.out.print(arrayForSort[i]);            } else {                System.out.print(arrayForSort[i] + " ,");            }        }        System.out.println("]");    }}

 

二、選擇排序:

選擇排序可以說是最簡單的一種排序方法:

1.找到數組中最小的那個元素

2.將最小的這個元素和數組中第一個元素交換位置

3.在剩下的元素中找到最小的的元素,與數組第二個元素交換位置

重複以上步驟,即可以得到有序數組。

 

代碼如下:

public class SelectionSort extends SortBase {    public Integer[] sort(Integer[] a) {        print("init",a);        Integer minIndex = 0;        Integer temp = 0;        for(int i=0;i<a.length;i++) {            minIndex = i;            for(int j=i+1;j<a.length;j++) {                if(a[j] < a[minIndex]) {                    minIndex = j;                }            }            temp = a[i];            a[i] = a[minIndex];            a[minIndex] = temp;                        print((i+1) + "",a);        }        return a;    }        public static void main(String[] args) {        Integer[] a = {2,1,5,9,0,6,8,7,3};        print("result",(new SelectionSort()).sort(a));    }}

 

 

我在代碼中打出了每次排序的結果,運行結果如下:

init: [2 ,1 ,5 ,9 ,0 ,6 ,8 ,7 ,3]1: [0 ,1 ,5 ,9 ,2 ,6 ,8 ,7 ,3]2: [0 ,1 ,5 ,9 ,2 ,6 ,8 ,7 ,3]3: [0 ,1 ,2 ,9 ,5 ,6 ,8 ,7 ,3]4: [0 ,1 ,2 ,3 ,5 ,6 ,8 ,7 ,9]5: [0 ,1 ,2 ,3 ,5 ,6 ,8 ,7 ,9]6: [0 ,1 ,2 ,3 ,5 ,6 ,8 ,7 ,9]7: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]8: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]9: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]result: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]

 

效率:對於長度為N的數組,選擇排序需要大約N²/2次比較和N次交換。也即最好、最差、平均時間效率均為O(n²),只需要一個輔助變數協助交換元素。

 

選擇排序可以看成是冒泡排序的擴充,一個是把最小或最大的選出來,再交換,一個是一直交換直到最大最小的出現在正確的位置上,選擇排序相對於冒泡排序,比較次數是一樣的,但是交換次數要少很多。

 

三、插入排序:

插入排序類似整理撲克牌,將每一張牌插到其他已經有序的牌中適當的位置。

插入排序由N-1趟排序組成,對於P=1到N-1趟,插入排序保證從位置0到位置P上的元素為已排序狀態。

簡單的說,就是插入排序總共需要排序N-1趟,從index為1開始,講該位置上的元素與之前的元素比較,放入合適的位置,這樣迴圈下來之後,即為有序數組。

 

代碼實現:

public class InsertionSort extends SortBase {    @Override    public Integer[] sort(Integer[] a) {        // TODO Auto-generated method stub        print("init",a);        Integer temp = 0;                for(int i=1;i<a.length;i++) {            //只能從當前索引往前迴圈,因為索引前的數組皆為有序的,索引只要確定當前索引的資料的為止即可            for(int j=i;j>0 && a[j] < a[j-1];j--) {                temp = a[j];                a[j] = a[j-1];                a[j-1] = temp;            }            print(i +"",a);        }                print("result",a);        return a;    }        public static void main(String[] args) {        Integer[] a = {2,1,5,9,0,6,8,7,3};        (new InsertionSort()).sort(a);    }    }

 

運行結果:

init: [2 ,1 ,5 ,9 ,0 ,6 ,8 ,7 ,3]1: [1 ,2 ,5 ,9 ,0 ,6 ,8 ,7 ,3]2: [1 ,2 ,5 ,9 ,0 ,6 ,8 ,7 ,3]3: [1 ,2 ,5 ,9 ,0 ,6 ,8 ,7 ,3]4: [0 ,1 ,2 ,5 ,9 ,6 ,8 ,7 ,3]5: [0 ,1 ,2 ,5 ,6 ,9 ,8 ,7 ,3]6: [0 ,1 ,2 ,5 ,6 ,8 ,9 ,7 ,3]7: [0 ,1 ,2 ,5 ,6 ,7 ,8 ,9 ,3]8: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]result: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]

 

 

效率:如果目標是把n個元素的序列升序排列,那麼採用插入排序存在最好情況和最壞情況。最好情況就是,序列已經是升序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可。最壞情況就是,序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。插入排序的賦值操作是比較操作的次數加上 (n-1)次。平均來說插入排序演算法的時間複雜度為O(n^2)

 

 

四、希爾排序

把記錄按步長 gap 分組,對每組記錄採用直接插入排序方法進行排序。

隨著步長逐漸減小,所分成的組包含的記錄越來越多,當步長的值減小到 1 時,整個資料合成為一組,構成一組有序記錄,則完成排序。

 

實現代碼:

public class ShellSort extends SortBase {    @Override    public Integer[] sort(Integer[] a) {        // TODO Auto-generated method stub        print("init",a);        Integer h = a.length;        Integer temp = 0;        while(h >= 1) {            for(int i=h;i<a.length;i++) {                for(int j=i;j>=h && a[j] < a[j-h];j -= h) {                    temp = a[j];                    a[j] = a[j-h];                    a[j-h] = temp;                                    }            }            h /= 9;        }        print("result",a);        return a;    }        public static void main(String[] args) {        Integer[] a = {2,1,5,9,0,6,8,7,3};        (new ShellSort()).sort(a);    }}

 

運行結果:

init: [2 ,1 ,5 ,9 ,0 ,6 ,8 ,7 ,3]1: [0 ,1 ,5 ,7 ,2 ,6 ,8 ,9 ,3]2: [0 ,1 ,2 ,6 ,3 ,7 ,5 ,9 ,8]3: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]result: [0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9]

 

效率:

最壞情況時間複雜度為:O(n^1.5),平均時間複雜度為O(nlogn)。

 

常用演算法之----選擇排序、插入排序和希爾排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.