算法-常見排序

冒泡排序

以升序來講,我們需要把最小的一個(gè)數(shù)通過換位置的方式調(diào)到最第一個(gè),那么第二小的數(shù)調(diào)到第二個(gè)位置。每次我們都從最后的一個(gè)數(shù)arr.lenth - 1進(jìn)行相鄰比較大小,小的往前調(diào),調(diào)動(dòng)至位置i, i從0開始

//排序的時(shí)間復(fù)雜度n*n   個(gè)人覺得(n-1)!更為精確
public static void orderByBubble(int a[]) {
            //先把前面的數(shù)排好.
        for(int i = 0 ; i < a.length - 1 ; i++) { 
            //從最后一個(gè)數(shù)開始往前冒泡.
            for(int j = a.length - 1 ; j > i; j--) {
                //每一輪調(diào)換最小的數(shù)到最前面》
                if(a[j] < a[j-1]) {
                    int temp = a[j];
                    a[j] = a[j - 1];
                    a[j - 1] = temp;
                }
            }
        }
}

選擇排序

選擇排序比較簡單,每次從第arr.lenth - i 個(gè)數(shù)中找到一個(gè)最大或者最小的數(shù),并把該數(shù)放到第i個(gè)位置

      /**
     * 每次選擇一個(gè)最小的數(shù)放在對(duì)應(yīng)的i位置.
     * 選擇排序.n*n
     * @param a
     */
    public static void orderBySelect(int a[]) {

        //這個(gè)代表第幾個(gè)數(shù)需要排序.最后n - 1(最后一個(gè))個(gè)數(shù)是不需要排序的,
        for(int i = 0 ; i < a.length - 1; i++) {
            int min = a[i];
            for(int j = i + 1 ; j < a.length ; j++ ) {
                if(min > a[j]) {
                    min = a[j];
                }
            }
            a[i] = min; //第i個(gè)數(shù)的序已經(jīng)排好.
        }
    }

直接插入排序

每次將一個(gè)無序的數(shù)a[i + 1]插入到一個(gè)有序的數(shù)組a[0] ~ a[i]之間,并且對(duì)該數(shù)組排序.

     /** 
     * 直接插入排序. n
     * @param a
     */
    public static void orderByDirectInsert(int a[]) {
        for(int i = 1 ; i < a.length ; i++) {
        // 在有序的數(shù)組里互換位置把己調(diào)整到合適的位置.
            for(int j = i; j > 0 ; j--) { 
                
        //if(a[n] > a[n - 1] && a[n] < a[n + 1])達(dá)到這個(gè)條件我們才說OK.終止循環(huán).
                //如果前面一個(gè)數(shù)要大,那么我們跟前面一個(gè)數(shù)換位置
                if(a[j - 1] > a[j]) {
                    int temp = a[j - 1];
                    a[j - 1] = a[j];
                    a[j] = temp;
                }
            }           
        }
    }

快速排序

快速排序,又名挖坑填數(shù)

/**
     * 時(shí)間復(fù)雜度n*logn, 空間復(fù)雜度logn
     * 快速排序》,這里就以a[0]為參照.任意數(shù)組中的元素為參照. 挖坑填數(shù).
     * @param a
     * @param l 初始值通常為0
     * @param r 初始值通常為a.length 可以針對(duì)某個(gè)區(qū)間排序.
     */
    public static void orderByQuick(int a[],int l,int r) {
        if(a == null) {
            throw new IllegalArgumentException("a[] == null exception");
        }
                
        if( l  < r) {
            //x只是個(gè)參考基數(shù).后面的動(dòng)作中a[l]最終被放在a[i]上.
            int i = l,j = r,x = a[l];
            while(i < j) {
                //這表示有一個(gè)數(shù)比x大了,退出循環(huán)的條件,是找到一個(gè)比X小的數(shù).
                while(i < j && a[j] >= x) { 
                    j--;
                }
將這個(gè)比x小的數(shù)放在左邊的位置
                a[i++] = a[j];
                
                while (i < j && a[i] < x ) {
                    i++;
                };
                a[j--] = a[i];
                
            }
            a[i] = x;
            orderByQuick(a, l, i - 1);//排左邊
            orderByQuick(a, i+1, r);//排右邊.
        }
    }

堆排序

二叉樹
構(gòu)建最大堆,調(diào)整最大堆,堆邏輯結(jié)構(gòu)表示為一個(gè)完全二叉樹,從最后一個(gè)非葉子節(jié)點(diǎn)開始構(gòu)建最大堆,將堆中的最大元素a[0] 和 最后一個(gè)元素互換位置,之后抹去已經(jīng)調(diào)整完成的最后一個(gè)元素,剩余的元素繼續(xù)調(diào)整出最大堆,以此循環(huán),直至所有元素調(diào)整完畢. 完全二叉樹每個(gè)節(jié)點(diǎn)下標(biāo)滿足公式n = i/2 - 1, n代表節(jié)點(diǎn),i代表節(jié)點(diǎn)下面的左孩子. 所以二叉樹最后一個(gè)節(jié)點(diǎn)下標(biāo)是lastNode = (a.lenth - 1)/2 - 1。
最大堆:即任何節(jié)點(diǎn)都比自己左右孩子節(jié)點(diǎn)大.由此根節(jié)點(diǎn)顯然最大.

/**
     * 這個(gè)需要構(gòu)建最大堆.
     */
    public static void builMaxHeap(int a[],int begain,int end) {
        int curPointValue = a[begain];
        int leftIndex = 2*begain + 1;
        for(int i = leftIndex; i*2 + 1 < end ;) 
        {
           //意思是右孩子大于左孩子.
            if(i + 1 < end && a[i + 1] > a[i]) {
               如果右孩子i++,那么下一輪循環(huán),將對(duì)該節(jié)點(diǎn)下的孩子進(jìn)行調(diào)整
如果沒有發(fā)生i++,則要調(diào)整的是左孩子下的所有節(jié)點(diǎn).
                i++;
            }
            // 取出左右孩子中最大的孩子
            if(a[i] > curPointValue) { 
                int temp = a[i];
                a[i] = curPointValue;
                a[begain] = temp;
            }else //表示當(dāng)前節(jié)點(diǎn)自己就是最大的,不必重排了.
                break;
            
            begain = i;
            
        }
        
    }
    
    /**
     * 堆排序. 堆是具有某些特性的完全二叉樹.每個(gè)節(jié)點(diǎn)的值要么都大于等于或者小于等于其子節(jié)點(diǎn).
     * @param a
     */
    public static void orderByHead(int a[]) {
        
        //構(gòu)建最大堆
        for(int i = (a.length - 1)/2 ; i >= 0 ; i--) 
        {
            builMaxHeap(a, i, a.length);
        }
        
        //調(diào)整最大堆.
        for(int j = a.length; j > 0 ; j--) {
            
            int temp = a[0];
            a[0] = a[j - 1];
            a[j-1] = temp;
            builMaxHeap(a,0, j);
        }
        
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 排序算法經(jīng)過了很長時(shí)間的演變,產(chǎn)生了很多種不同的方法。對(duì)于初學(xué)者來說,對(duì)它們進(jìn)行整理便于理解記憶顯得很重要。每種算...
    DNIX閱讀 2,048評(píng)論 0 2
  • 總結(jié)一下常見的排序算法。 排序分內(nèi)排序和外排序。內(nèi)排序:指在排序期間數(shù)據(jù)對(duì)象全部存放在內(nèi)存的排序。外排序:指在排序...
    jiangliang閱讀 1,519評(píng)論 0 1
  • 1 序 2016年6月25日夜,帝都,天下著大雨,拖著行李箱和同學(xué)在校門口照了最后一張合照,搬離寢室打車去了提前租...
    RichardJieChen閱讀 5,377評(píng)論 0 12
  • 概述:排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,828評(píng)論 0 15
  • 我將你,一直保存在我心中一直,不管你會(huì)離我有多遠(yuǎn)我們總會(huì)在那個(gè)路口相遇 上篇回顧:蘇沐沐被蕭霖辰帶去見了客戶后,交...
    陌靜寧閱讀 223評(píng)論 0 0

友情鏈接更多精彩內(nèi)容