排序算法

冒泡排序

時間復(fù)雜度O(n^2)

public static void bubbleSort(int[] arr){
        int temp=0;
        boolean flag=false;
        for(int i=0;i<arr.length-1;i++){
            for(int j=0;j<arr.length-1-i;j++){
                if(arr[j]>arr[j+1])
                {
                    flag=true;
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
            if(!flag)
                return;
            else
                flag=false;
        }
    }

選擇排序

時間復(fù)雜度O(n^2)

 public static void selectSort(int[] arr){
        for(int i=0;i<arr.length-1;i++){
            int minIndex=i;
            int min=arr[i];
            for(int j=i+1;j<arr.length;j++){
                if(min>arr[j]){
                    min=arr[j];
                    minIndex=j;
                }
            }
            if(minIndex!=i){
                arr[minIndex]=arr[i];
                arr[i]=min;
            }
        }
    }
冒泡排序與選擇排序的區(qū)別

冒泡排序是將“最大值”不斷移向最后杀怠,比如第一次遍歷搂捧,將全部數(shù)的最大值移到最后一個位置,第二次遍歷淳地,將從開始到倒數(shù)第二個數(shù)中的最大值移到倒數(shù)第二個位置,以此類推。過程中可能存在多次交換

選擇排序是首先將第一個數(shù)到最后中的最小值與第一個數(shù)交換额获,然后從第二個數(shù)開始,一直到最后恭应,找出最小值抄邀,與第二個數(shù)交換,以此類推昼榛。在一次遍歷中有且只交換一次

插入排序

時間復(fù)雜度O(n^2)

 public static void insertSort(int[] arr){
        for(int i=1;i<arr.length;i++){
            int insertVal=arr[i];
            int insertIndex=i-1;
            while(insertIndex>=0&&insertVal<arr[insertIndex]){
                arr[insertIndex+1]=arr[insertIndex];
                insertIndex--;
            }if(insertIndex+1!=i){
                arr[insertIndex+1]=insertVal;
            }
        }
    }

原理

插入排序原理

希爾排序

希爾排序是希爾(Donald Shell)于1959年提出的一種排序算法境肾。希爾排序也是一種插入排序,它是簡單插入排序經(jīng)過改進(jìn)之后的一個更高效的版本胆屿,也稱為縮小增量排序奥喻,同時該算法是沖破O(n2)的第一批算法之一

希爾排序是把記錄按下標(biāo)的一定增量分組,對每組使用直接插入排序算法排序莺掠;隨著增量逐漸減少衫嵌,每組包含的關(guān)鍵詞越來越多,當(dāng)增量減至1時彻秆,整個文件恰被分成一組楔绞,算法便終止。

希爾排序的時間復(fù)雜度比較模糊唇兑,它取決于增量酒朵,大概范圍是O(n^(1.3-2)),但是可以肯定的是希爾排序比直接插入排序要更有效率

public static void shellSort(int[] arr){
        int temp=0;
        int count=0;
        for(int gap=arr.length/2;gap>0;gap/=2){
            for(int i=gap;i<arr.length;i++)
                for(int j=i-gap;j>=0;j-=gap)
                    if(arr[j]>arr[j+gap]){
                        temp=arr[j];
                        arr[j]=arr[j+gap];
                        arr[j+gap]=temp;
                    }

        }
    }
希爾排序

希爾排序的原理很好理解扎附,但是代碼需要思考一下:

for(int gap=arr.length/2;gap>0;gap/=2){
            for(int i=gap;i<arr.length;i++)
                for(int j=i-gap;j>=0;j-=gap)
                    if(arr[j]>arr[j+gap]){
                        temp=arr[j];
                        arr[j]=arr[j+gap];
                        arr[j+gap]=temp;
                    }

        }

關(guān)于這里蔫耽,最外層循環(huán)是增量,中間層的 i 從gap開始,即從第一個分組的第二個元素開始匙铡,也就是說跳過所有分組的第一個元素图甜,以便接下來進(jìn)行判斷,交換位置

最里層 j 從 i-gap開始鳖眼,也就是從 i 所在分組的前一個元素開始判斷黑毅,j 遞減gap,一直到0钦讳,也就是將 arr[i]移到所在分組的排序后的位置
矿瘦,也就是之前的插入排序

i 一直遍歷到arr.length,從而將所有分組的所有元素(從第二個開始)都在所在分組進(jìn)行了插入排序

最后隨著gap折減到0愿卒,排序完成

快速排序

快速排序(Quicksort)是對冒泡排序的一種改進(jìn)缚去。基本思想是:通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分琼开,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小易结,然后再按此方法對這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個排序過程可以遞歸進(jìn)行稠通,以此達(dá)到整個數(shù)據(jù)變成有序序列

快速排序的平均時間復(fù)雜度是O(nlogn)衬衬,最壞情況是O(n^2)

  public static void main(String[] args) {
        int[] arr=new int[]{9,8,7,6,5,4,3,2,1,0};
        quickSort(arr,0,arr.length-1);
        for(int e:arr)
            System.out.print(e);

    }
    public  static void quickSort(int[] arr,int left,int right){
        if(arr==null||arr.length==0)
            return;
        if(left>right)
            return;
        int key=arr[left];
        int l=left;
        int r=right;
        int temp=0;
        while(l!=r){
            while(arr[r]>=key&&l<r)
                r--;
            while(arr[l]<=key&&l<r)
                l++;
            if(l<r){
                temp=arr[l];
                arr[l]=arr[r];
                arr[r]=temp;
            }
        }
        arr[left]=arr[r];
        arr[l]=key;
        quickSort(arr,left,l-1);
        quickSort(arr,l+1,right);
    }
快速排序

歸并排序

歸并排序(MERGE-SORT)是利用歸并的思想實現(xiàn)的排序方法,該算法采用經(jīng)典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然后遞歸求解改橘,而治(conquer)的階段則將分的階段得到的各答案"修補(bǔ)"在一起滋尉,即分而治之)。

歸并排序的時間復(fù)雜度是O(nlogn)


public class MergeSort {
    public static void main(String[] args) {
        int[] arr=new int[]{9,8,7,6,5,4,3,2,1,0};
        int[] temp=new int[arr.length];
        mergeSort(arr,0,arr.length-1,temp);
        for(int e:arr)
            System.out.print(e);
    }
    public static void mergeSort(int[]arr,int left,int right,int[]temp){
        if(left<right){
            int mid=(left+right)/2;
            mergeSort(arr,left,mid,temp);
            mergeSort(arr,mid+1,right,temp);
            merge(arr,left,mid,right,temp);
        }
    }
    public static void merge(int[] arr,int left,int mid,int right,int[] temp){
        int i=left;
        int j=mid+1;
        int t=0;
        while(i<=mid&&j<=right){
            if(arr[i]<=arr[j])
                temp[t++]=arr[i++];
            else
                temp[t++]=arr[j++];
        }
        while(i<=mid)
            temp[t++]=arr[i++];
        while(j<=right)
            temp[t++]=arr[j++];
        t=0;
        int tempLeft=left;
        while(tempLeft<=right)
            arr[tempLeft++]=temp[t++];
    }
}

基數(shù)排序

基數(shù)排序(桶排序)介紹:
1)基數(shù)排序(radix sort)屬于"分配式排序"(distribution sort)飞主,又稱"桶子法”(bucket sort)或bin sort狮惜、顧名思義,它是通過鍵值的各個位的值,將要排序的元素分配至某些“桶"中達(dá)到排序的作用
2)基數(shù)排序法是屬于穩(wěn)定性的排序碌识,基數(shù)排序法的是效率高的穩(wěn)定性排序法碾篡,穩(wěn)定性排序指:如一個數(shù)組原來為3,1,4,1排序后為1,1,3,4,紅色的1仍然在前面筏餐。
3)基數(shù)排序(Radix Sort)是桶排序的擴(kuò)展
4)基數(shù)排序是1887年赫爾曼·何樂禮發(fā)明的开泽。它是這樣實現(xiàn)的:將整數(shù)按位數(shù)切割成不同的數(shù)字,然后按每個位數(shù)分別比較
5)基數(shù)排序法的時間復(fù)雜度為O (nlog(r)m)魁瞪,其中r為所采取的基數(shù)穆律,而m為堆數(shù)
基數(shù)排序基本思想
將所有待比較數(shù)值統(tǒng)一為同樣的數(shù)位長度.?dāng)?shù)位較短的數(shù)前面補(bǔ)零。然后导俘,從最低位開始峦耘,依次進(jìn)行一次排序。這樣從最低位排序一直到最高位排序完成以后,數(shù)列就變成一個有序序列旅薄。

例如:將數(shù)組{53,3,542,748,14,214}使用基數(shù)排序,進(jìn)行升序排序

public static void radixSort(int[] arr){
        int max=arr[0];
        for(int i=0;i<arr.length;i++){
            max=max>arr[i]?max:arr[i];
        }
        int maxLength=(max+"").length();//數(shù)字最大位數(shù)
        int[][] bucket=new int[10][arr.length];//十個桶子辅髓,每個深為arr.length
        int[] bucketElementCounts=new int[10];//用于記錄每個桶子里面存放了幾個數(shù)據(jù),便于取出
        for(int i=0,n=1;i<maxLength;i++,n*=10){//次數(shù)為數(shù)字最大位數(shù)的循環(huán)
            for(int j=0;j<arr.length;j++)//依次放入桶子
            {
                int digitOfElement=arr[j]/n%10;
                bucket[digitOfElement][bucketElementCounts[digitOfElement]]=arr[j];
                bucketElementCounts[digitOfElement]++;
            }
            int index=0;
            for(int k=0;k<10;k++){//依次取出
                if(bucketElementCounts[k]!=0){
                    for(int m=0;m<bucketElementCounts[k];m++)
                        arr[index++]=bucket[k][m];
                }
                bucketElementCounts[k]=0;//記得將桶子中存放個數(shù)清零 
            }
        }
    }

堆排序

堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)而設(shè)計的一種排序算法,是一種選擇排序洛口,它的最壞矫付,最好.平均時間復(fù)雜度均為O(nlogn),它也是不穩(wěn)定排序(不能保證相同的兩個數(shù)的位置和原來一樣)

堆是具有以下性質(zhì)的完全二叉樹(葉子節(jié)點只出現(xiàn)在最后一層或倒數(shù)第二層)∶

  1. 每個結(jié)點的值都大于或等于其左右孩子結(jié)點的值绍弟,稱為大頂堆
    (注意:沒有要求結(jié)點的左孩子的值和右孩子的值的大小關(guān)系)

  2. 每個結(jié)點的值都小于或等于其左右孩子結(jié)點的值,稱為小頂堆



一般升序采用大頂堆骤坐,降序用小頂堆
堆排序的基本思想是:

  1. 將待排序序列構(gòu)造成一個大頂堆
  2. 此時轧苫,整個序列的最大值就是堆頂?shù)母?jié)點
  3. 將其與末尾元素進(jìn)行交換,此時末尾就為最大值
  4. 然后將剩余n-1個元素重新構(gòu)造成一個堆,這樣會得到n個元素的次小值姿骏。如此反復(fù)執(zhí)行,便能得到一個有序序列了
 public static void heapSort(int[] arr){
        int temp=0;
        for(int i=arr.length/2-1;i>=0;i--)
            adjustHeap(arr,i,arr.length);

        for(int j=arr.length-1;j>0;j--){
            temp=arr[j];
            arr[j]=arr[0];
            arr[0]=temp;
            adjustHeap(arr,0,j);
        }
    }

    /**
     *
     * @param arr 待調(diào)整數(shù)組
     * @param i 非葉子節(jié)點在數(shù)組中的索引
     * @param length 表示對多少個元素進(jìn)行調(diào)整身笤,是遞減的
     */
    public static void adjustHeap(int[] arr,int i,int length){
        int temp=arr[i];
        for(int k=i*2+1;k<length;k=k*2+1){
            if(k+1<length&&arr[k]<arr[k+1])
                k++;
            if(arr[k]>temp)
            {
                arr[i]=arr[k];
                arr[k]=temp;
                i=k;
            }else
                break;
        }
    }

https://www.cnblogs.com/coding-996/p/12275710.html
https://www.cnblogs.com/chengxiao/p/6104371.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末豹悬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子液荸,更是在濱河造成了極大的恐慌瞻佛,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娇钱,死亡現(xiàn)場離奇詭異伤柄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)文搂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門适刀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人煤蹭,你說我怎么就攤上這事笔喉。” “怎么了硝皂?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵常挚,是天一觀的道長。 經(jīng)常有香客問我稽物,道長奄毡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任贝或,我火速辦了婚禮吼过,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘傀缩。我一直安慰自己那先,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布赡艰。 她就那樣靜靜地躺著售淡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上揖闸,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天揍堕,我揣著相機(jī)與錄音,去河邊找鬼汤纸。 笑死衩茸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贮泞。 我是一名探鬼主播楞慈,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼啃擦!你這毒婦竟也來了囊蓝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤令蛉,失蹤者是張志新(化名)和其女友劉穎聚霜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體珠叔,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝎宇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了祷安。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姥芥。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖辆憔,靈堂內(nèi)的尸體忽然破棺而出撇眯,到底是詐尸還是另有隱情,我是刑警寧澤虱咧,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布熊榛,位于F島的核電站,受9級特大地震影響腕巡,放射性物質(zhì)發(fā)生泄漏玄坦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一绘沉、第九天 我趴在偏房一處隱蔽的房頂上張望煎楣。 院中可真熱鬧,春花似錦车伞、人聲如沸择懂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽困曙。三九已至表伦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慷丽,已是汗流浹背蹦哼。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留要糊,地道東北人纲熏。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像锄俄,于是被迫代替她去往敵國和親局劲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容