国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?/h1>

這篇具有很好參考價(jià)值的文章主要介紹了【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

插入排序

直接插入排序

  • 算法基本思想:(從大到小排序)
    在一個(gè)非遞減的有序數(shù)組中,要新增一個(gè)元素x,有兩個(gè)方法:
    1.從數(shù)組的頭部開(kāi)始向后遍歷,尋找第一個(gè)比x 大的元素y,從y元素開(kāi)始的所有元素全部向后移動(dòng),最后將x元素插入數(shù)組。(×)
    2.從數(shù)組的尾部開(kāi)始向后向前遍歷,尋找第一個(gè)比x小的元素k,從k元素開(kāi)始,后面每個(gè)元素都向后移動(dòng),最后將元素x插入數(shù)組。(√)
    在這里插入圖片描述

【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
那么我們應(yīng)該選擇哪種方式呢?
其實(shí)仔細(xì)思考一下,我們很容易會(huì)想到選擇第2種方式,原因也很簡(jiǎn)單:在尋找第一個(gè)比x小的元素k時(shí),我們可以邊把比 x 大的元素往后移動(dòng)。

因此,我們對(duì)一個(gè)數(shù)組排序時(shí),可以從第2個(gè)元素開(kāi)始,看作是把元素插入一個(gè)已經(jīng)有序的數(shù)組中。
具體代碼如下:

public static void insertSort1(int[] array) {
        for(int i = 1; i < array.length; i++) {
            // 記錄 i 下標(biāo)的元素,防止比 i下標(biāo) 大的元素向后移動(dòng)將其覆蓋
            int tmp = array[i];
            // 從下標(biāo)為 i-1的元素開(kāi)始遍歷, 比 array[i]大的元素都向后移動(dòng)
            int j = i -1;
            for(; j >= 0; j--) {
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                } else {
    		// 此時(shí)array[j] < array[i],且 j + 1下標(biāo) 為 array[i] 在已排序元素中的位置
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

時(shí)間復(fù)雜度:O(n2)。最好情況是數(shù)組已經(jīng)有序,只需比較n-1次,時(shí)間復(fù)雜度為O(n);最壞情況是數(shù)組為待排序順序的逆序,需要(n-1)(n-1)…1次,時(shí)間復(fù)雜度為O(n2)。
空間復(fù)雜度:O(1)。記錄每次待排序的元素的額外空間。
穩(wěn)定性:穩(wěn)定。
適用情況:數(shù)組基本有序的情況下。

折半插入排序

  • 算法基本思想:(從大到小排序)
    折半插入排序的本質(zhì)也是在一個(gè)已經(jīng)有序的數(shù)組的插入一個(gè)元素,與直接插入排序的唯一區(qū)別是:折半插入排序是利用二分查找找到那個(gè)合適的插入位置。

  • 二分查找的基本步驟:
    將要插入元素跟區(qū)間的中間元素對(duì)比,將待查找的區(qū)間縮小為之前的一半,直到找到要查找的元素,或者區(qū)間被縮小為0(即 left>right ,數(shù)組中不存在指定元素)。
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    注意事項(xiàng):
    (1)若插入元素在數(shù)組不存在(如上圖所示情況),則插入元素的下標(biāo)應(yīng)為 right+1,因此需要將 right+1 下標(biāo) 開(kāi)始的所有元素全部向后移動(dòng)。
    (2)若插入元素與 mid 下標(biāo)的元素相等,為了操作的統(tǒng)一性,我們可以使 right=mid-1,這樣一來(lái),待插入元素的下標(biāo)也為 right+1 ,接下來(lái)同樣將 right+1 下標(biāo) 開(kāi)始的所有元素全部向后移動(dòng)。

具體代碼實(shí)現(xiàn)如下:

    public static void binaryInsertSort(int[] array) {
        for (int i = 1; i < array.length; i++) {
            int left = 0, right = i - 1;
            int mid = (left + right) / 2;
            int target = array[i];      // 待插入的元素
            // 1. 找到合適的插入位置
            while(left <= right) {
                mid = (left + right) / 2;
                if(array[mid] < target) left = mid + 1;
             // 出現(xiàn) array[mid] == target,同樣進(jìn)行此操作,可保證 元素插入下標(biāo)的一致性
                else right = mid -1;	
            }
            // 2. 在已排序好的數(shù)組區(qū)間中,將mid開(kāi)始的元素,從后向前依次向后移動(dòng)
            for (int j = i - 1; j >= right + 1; j--) {
                array[j+1] = array[j];
            }
            // 3. 將 array[i] 插入到 mid 位置
            array[right + 1] = target;
        }
    }

時(shí)間復(fù)雜度:O(n2)。在平均情況下,折半插入排序 的元素移動(dòng)次數(shù)與 直接插入排序 相同, 僅減少了元素間的比較次數(shù),因此時(shí)間復(fù)雜度仍為O(n2)。
空間復(fù)雜度:O(1)。記錄每次待排序的元素的額外空間。
穩(wěn)定性:穩(wěn)定。
適用情況:數(shù)組基本有序且數(shù)組元素較多,可一定程度減少元素間的比較次數(shù)。

希爾排序(縮小增量排序)

  • 算法基本原理:
    希爾排序本質(zhì)上是一種優(yōu)化的"插入排序",其主要思想是“分組”和“縮小增量”。
    分組”即將一個(gè)待排序的數(shù)組分為多組數(shù)據(jù),對(duì)每組數(shù)據(jù)分別進(jìn)行插入排序,使得當(dāng)前排序完成后,每個(gè)小組的數(shù)據(jù)變得局部有序,整個(gè)數(shù)組基本有序,從而達(dá)到預(yù)排序的效果(以便提高最終直接插入排序的效率).
    縮小增量”即在整個(gè)數(shù)組的預(yù)排序過(guò)程中,逐漸減少分組數(shù)量,增大每組的數(shù)據(jù)量,直到分組數(shù)量n=1時(shí),針對(duì)之前的預(yù)排序結(jié)果,進(jìn)行一次直接插入排序。

關(guān)于分組?
對(duì)于前面的分組,并不是如下圖的“逐段分割”式分組方式。(×)
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

但事實(shí)上,通過(guò)上述例子我們可以看出,經(jīng)過(guò)幾次“預(yù)排序”,似乎并沒(méi)有達(dá)到預(yù)期的基本有序的效果,因?yàn)?1 和 2 這樣較小的數(shù)字依然在后面, 12 這個(gè)比較大的數(shù)子也仍然處于中間的位置,沒(méi)有加快直接插入排序的速度。

這樣的“逐段式”分組方式顯然是不夠合理的,因此這里正確的分組的方式是:將每間隔距離為“增量”大小 gap 的元素分為一組(如下圖)。(√)

【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
這樣"跳躍式"的分組的好處是:若較大的元素在前面,通過(guò)"跳躍式"分組后,較大的元素有機(jī)會(huì)通過(guò)插入排序直接移動(dòng)到后面;若較小的元素在后面,通過(guò)"跳躍式"分組后,較小的元素有機(jī)會(huì)通過(guò)插入排序直接移動(dòng)到前面.

關(guān)于分組后插入排序的方式?
分組后,并不是依次對(duì)每組元素進(jìn)行插入排序,而是從第一組的第 2 個(gè)元素 即下標(biāo)為 gap 的元素開(kāi)始,之后的每個(gè)元素進(jìn)行間距為“增量”大小的插入排序。(如下圖, gap = 3)
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

關(guān)于 gap 的取值?
gap 的取值有很多種方式,不同取值方式所得到排序時(shí)間復(fù)雜度有所不同,目前并沒(méi)有一種確定的最佳增量序列,但唯一確定的是最后一個(gè)增量應(yīng)為 1 。在本文的代碼實(shí)現(xiàn)中,當(dāng)待排序排序的元素個(gè)數(shù)為 n, gap 的初始值為 n/2,隨后每次 gap = gap/2, 直到 gap 為1,完成排序。

希爾排序的具體代碼實(shí)現(xiàn)如下:

	public static void shellSort(int[] array){
        // 當(dāng)前數(shù)組只有一個(gè)元素,不需要進(jìn)行排序
        if(array.length < 2) return;
        
        // 保證第一次的 gap = n/2,最后一次排序 gap = 1
        int gap = array.length;
        while(gap > 1) {
            gap = gap / 2;
            shell(array, gap);
        }
    }
    private static void shell(int[] array, int gap) {
        for(int i = gap; i < array.length; i++) {
            int tmp = array[i];
            // 若array[j] > tmp,則該元素向前移動(dòng)
   			// j 繼續(xù)向前移動(dòng) gap 個(gè)位置,重復(fù)上述過(guò)程,直到 array[j] <= tmp 或 j < 0  
            int j = i - gap;
            for(; j >= 0; j -= gap) {
                if(array[j] > tmp) {
                    array[j+gap] = array[j];
                }else {
                    break;
                }
            }
            array[j+gap] = tmp;
        }
    }

時(shí)間復(fù)雜度:O(n ^ 1.25) - O(1.6 * n ^ 1.25)。
空間復(fù)雜度:O(1)。
穩(wěn)定性:不穩(wěn)定。
適用情況:適合初始記錄無(wú)序,元素個(gè)數(shù) n 較大時(shí)的情況。

選擇排序

簡(jiǎn)單選擇排序

  • 算法基本原理:(從大到小排序)
    (若要求從小到大排序)每次從待排序數(shù)組的區(qū)間中順序遍歷,記錄最大元素的下標(biāo),然后與待排序數(shù)組區(qū)間的最后一個(gè)元素交換。
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    具體代碼如下:
    public static void selectSort(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            // 需要找 n - 1 次, 每次從第一個(gè)元素開(kāi)始向后遍歷
            int maxIndex = 0;
            for (int j = 1; j < array.length - i; j++) {
                if(array[j] > array[maxIndex]) maxIndex = j;
            }
            swap(array, array.length - 1 - i, maxIndex);
        }
    }
    private static void swap(int[] array, int x, int y) {
        int tmp = array[x];
        array[x] = array[y];
        array[y] = tmp;
    }

時(shí)間復(fù)雜度:O(n2)。在任何情況下,第 i 趟尋找最大的元素時(shí),都需要比較 n - i 次,因此n - 1趟排序的時(shí)間復(fù)雜度為O(n2)。
空間復(fù)雜度:O(1)。需要一個(gè)額外空間進(jìn)行元素交換。
穩(wěn)定性:不穩(wěn)定(可通過(guò)代碼改善變得穩(wěn)定)。
適用情況:無(wú)論數(shù)組的有序性如何,簡(jiǎn)單選擇排序的時(shí)間復(fù)雜度都為O(n2),只適合數(shù)據(jù)量小的排序,一般不推薦使用。

堆排序

堆的說(shuō)明:將數(shù)組按下標(biāo)從小到大抽象成為一顆二叉樹(shù),再通過(guò)一定的調(diào)整手段,使該二叉樹(shù)具有以下特點(diǎn):每顆樹(shù)根結(jié)點(diǎn)的值 > 其左右子樹(shù)根結(jié)點(diǎn)的值(大根堆) 或者 每顆樹(shù)根結(jié)點(diǎn)的值 < 其左右子樹(shù)根結(jié)點(diǎn)的值(小根堆) 。(如下圖所示)
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

  • 算法基本思想:(從大到小排序)
  1. 把待排序數(shù)組調(diào)整成一個(gè)大根堆,每次將堆頂元素(即根結(jié)點(diǎn))與待排序堆的最后一個(gè)元素交換
  2. 接著將剩下待排序數(shù)組重新調(diào)整成堆(重新上述步驟,最終完成排序)。(如下圖)
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    那么如何將數(shù)組調(diào)整成大根堆呢?(以最開(kāi)始的原數(shù)組為例)
  3. 從二叉樹(shù)的最后一個(gè)非終端結(jié)點(diǎn)(即度不為0的結(jié)點(diǎn))開(kāi)始,將它前面的每個(gè)結(jié)點(diǎn)都進(jìn)行向上調(diào)整。(這里是下標(biāo)0-2的結(jié)點(diǎn))
  4. 對(duì)每個(gè)結(jié)點(diǎn)(這里暫且將該結(jié)點(diǎn)稱(chēng)作root結(jié)點(diǎn))進(jìn)行調(diào)整時(shí),需把 root結(jié)點(diǎn) 值的大小與其左右孩子進(jìn)行比較,若 root結(jié)點(diǎn) 的值較小,則將較大的孩子結(jié)點(diǎn)與 root結(jié)點(diǎn) 的值交換。(注意:若交換的孩子結(jié)點(diǎn)也有孩子,仍需繼續(xù)將該孩子進(jìn)行比較和調(diào)整,當(dāng)且僅當(dāng) root結(jié)點(diǎn) 所在的整顆樹(shù)都調(diào)整成為大根堆,該結(jié)點(diǎn)才算調(diào)整完成)。
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
    【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

建立大根堆的具體代碼如下:

		// array為原始數(shù)組
    private static void createBigHeap(int[] array) {
    	// 最后一個(gè)非終端結(jié)點(diǎn)下標(biāo)為(array.length-2) / 2
    	// 對(duì)下標(biāo)為(array.length-2) / 2 到 下標(biāo)為0的結(jié)點(diǎn)依次進(jìn)行“向上調(diào)整 ”
        for(int parent = (array.length-2) / 2; parent >= 0; parent-- ) {
            shiftDown(array,parent, array.length);
        }
    }

	// root表示當(dāng)前調(diào)整的數(shù)的根結(jié)點(diǎn)下標(biāo),len表示待調(diào)整的整個(gè)數(shù)組的長(zhǎng)度
    private static void shiftDown(int[] array, int root, int len) {
        int parent = root;
        int child = root * 2 + 1;
        // 防止出現(xiàn)需要多次調(diào)整的情況
        while(child < len) {
       // child + 1 判斷該結(jié)點(diǎn)是否有右孩子,有則通過(guò)比較選出左右孩子的較大值
            if(child + 1 < len && array[child] < array[child+1]) {
                child = child + 1;
            }
       		// 判斷是否需要交換
            if(array[child] > array[parent]) {
                swap(array,child,parent);
                parent = child;
                child = parent * 2 + 1;
            }else {
                break;
            }
        }
    }

經(jīng)過(guò)上述調(diào)整的大根堆,就可以正式開(kāi)始堆排序:

  1. 把待排序數(shù)組調(diào)整成一個(gè)大根堆,每次將堆頂元素(即根結(jié)點(diǎn))與待排序堆的最后一個(gè)元素交換。
  2. 接著將剩下待排序數(shù)組重新調(diào)整成堆。(重新1,2步驟)

堆排序具體代碼如下:

public static void heapSort2(int[] array) {
		// 建立大根堆
        createBigHeap(array);
        int end = array.length - 1;
        while(end > 0) {
        	// 交換堆頂元素 與 待排序區(qū)間的末尾元素
            swap(array, 0, end);
            // 重新調(diào)整將剩下區(qū)間調(diào)整成大根堆
            shiftDown(array, 0, end);
            end--;
        }
    }

時(shí)間復(fù)雜度:O(nlog? n)。最壞情況下的時(shí)間時(shí)間復(fù)雜度為也穩(wěn)定在O(n * log? n)。
空間復(fù)雜度:O(1)。需要一個(gè)額外空間進(jìn)行元素交換。
穩(wěn)定性:不穩(wěn)定。
適用情況堆排序是一種較快的排序算法,它與快速排序,歸并排序的平均時(shí)間都為O(n
log? n),適用于數(shù)據(jù)量較大時(shí)的排序。

交換排序

冒泡排序

  • 算法基本思想:(從大到小排序)
    通過(guò)兩兩比較相鄰記錄的關(guān)鍵字,如果后一個(gè)元素的值大于前一個(gè)元素,則將兩個(gè)元素進(jìn)行交換,從而使關(guān)鍵字大的元素如煮開(kāi)水時(shí)的“氣泡”一樣逐漸向上“漂浮”(右移)。

  • 算法步驟:
    (1)具有 n 個(gè)元素的數(shù)組,進(jìn)行 n-1 趟冒泡排序。
    (2)每趟冒泡排序從第一個(gè)元素開(kāi)始向后遍歷,相鄰兩兩元素比較,將關(guān)鍵字大的元素交換到后面,直到當(dāng)前排序區(qū)間最大元素到區(qū)間末尾,這趟冒泡排序結(jié)束。

第一趟的交換過(guò)程如下圖:(某待排序數(shù)組)
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
當(dāng)?shù)诙伺判蛲瓿珊?,?shù)組的元素分布情況如下:
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
不難發(fā)現(xiàn),在第二趟排序結(jié)束后,數(shù)組已經(jīng)屬于有序狀態(tài),很明顯進(jìn)行接下來(lái)的幾趟排序是“多此一舉”的。
因此我們可以對(duì)普通的冒泡排序做一個(gè)小小的優(yōu)化:即設(shè)置一個(gè)標(biāo)志位 flag = 1,當(dāng)次輪排序過(guò)程發(fā)生了元素交換,則將 flag 置為 0,當(dāng)本趟排序完成后,若 flag == 1,則代表數(shù)組已經(jīng)有序,直接跳出整個(gè)循環(huán),完成排序操作。

冒泡排序代碼實(shí)現(xiàn)如下

	public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            // 判斷是否繼續(xù)冒泡排序
            int flag = 1;       
            for (int j = 0; j < array.length - 1 - i; j++) {
                if(array[j] > array[j+1]) {
                    swap(array,j,j+1);
                    flag = 0;
                }
            }
            if(flag == 1) break;
        }
    }

時(shí)間復(fù)雜度:O(n2)。即使設(shè)置標(biāo)志位對(duì)冒泡排序進(jìn)行優(yōu)化,但排序的平均時(shí)間復(fù)雜度仍為O(n2)。
空間復(fù)雜度:O(1)。需要一個(gè)額外空間進(jìn)行元素交換。
穩(wěn)定性:穩(wěn)定。
適用情況:適合數(shù)據(jù)量較小的數(shù)據(jù)排序,當(dāng)數(shù)據(jù)規(guī)模較大時(shí),排序效率較低。

快速排序

  • 算法基本思想:
    快速排序由冒泡排序改進(jìn)而成??焖倥判虿捎谩胺种巍钡乃枷?,即把一個(gè)大問(wèn)題分解成為多個(gè)子問(wèn)題,通過(guò)解決每個(gè)子問(wèn)題,從而解決整個(gè)大問(wèn)題。
    在每個(gè)子問(wèn)題中,需要選一個(gè)元素值 pivot 作為“基準(zhǔn)”,通過(guò)一定次數(shù)的兩兩元素交換,最終將某個(gè)區(qū)間區(qū)間分為兩個(gè)區(qū)間,左區(qū)間的元素全部不大于 pivot,右區(qū)間的元素全部不小于 pivot。

  • 快速排序區(qū)間劃分的兩個(gè)常見(jiàn)方式:
    (1) Hoare法(2)“挖坑”法

Hoare法

  1. 在待排序區(qū)間中,選取第一個(gè)元素作為基準(zhǔn)值 pivotkey ,定義 left 和 right 兩個(gè)“指針”,其中l(wèi)eft 指向待排序區(qū)間的第一個(gè)元素,right 指向待排序區(qū)間的最后一個(gè)元素。right 指針向左遍歷尋找第一個(gè)小于 pivot 的元素,left 指針向右遍歷尋找第一個(gè)大于 pivot 的元素, 隨后交換 left 和 right 所指向的元素。
  2. 重復(fù)上述步驟,直至 left 指針和 right 指針相遇。將 基準(zhǔn)元素pivot 與 right(left)指針交換,完成分區(qū)操作。
  3. 將 pivot 左區(qū)間和右區(qū)間分為兩個(gè)新的待排序區(qū)間,重復(fù)1,2步驟,最終完成排序。

具體的排序過(guò)程如下圖所示:
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
下面的分區(qū)過(guò)程省略


通過(guò)以上過(guò)程我們不難看出:快速排序是一個(gè)采用遞歸思想的排序過(guò)程。

注意:當(dāng)你也嘗試著去模擬上述的過(guò)程,你也許會(huì)發(fā)現(xiàn):好像將left(right)“指針”指向的元素 與 第一個(gè)元素交換后,并不會(huì)出現(xiàn)分區(qū)的現(xiàn)象。

【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

那么造成這種現(xiàn)象的原因是否與 left“指針” 和 right“指針” 移動(dòng)的先后順序有關(guān)呢?
答案是肯定的,這種情況是因?yàn)樵谀承?shù)據(jù)先移動(dòng) left“指針”造成的。因此,在每次尋找符合交換條件的元素時(shí),應(yīng)先讓 right“指針”向左尋找待交換的元素

注意left“指針”要尋找比 pivotkey 大的元素,right“指針”要尋找比 pivotkey 小的元素,那循環(huán)找元素的條件能否直接寫(xiě)成 array[left] < pivotkey 和 array[right] > pivotkey呢?
答案是否定的。原因是數(shù)組可能出現(xiàn) 元素值key == pivotkey 的情況,如果寫(xiě)成上述判斷條件,可能會(huì)出現(xiàn)排序出差的情況。

Hoare法具體的代碼實(shí)現(xiàn)如下:

    public static void quiackSort(int[] array) {
        quick(array, 0, array.length - 1);
    }
    
    private static void quick(int[] array, int left, int right) {
        //代表此時(shí) 此時(shí)排序區(qū)間 只有一個(gè)元素 或者 排序區(qū)間不存在
        if(left >= right) return;
        
        // 在 partition方法中,完成分區(qū)操作,并返回 pivot的下標(biāo)
        int pivot = partition(array, left, right);
        // 對(duì) pivot 的左右區(qū)間進(jìn)行遞歸操作
        quick(array,pivot + 1, right);
        quick(array,left, pivot - 1);
    }
    
    private static int partition(int[] array, int left, int right) {
        int tmp = array[left];
        int i = left;	// 記錄基準(zhǔn)值的下標(biāo)
        while(left < right) {
            //必須先讓 right 去尋找比tmp小的元素, 因?yàn)檫@樣可以防止 一個(gè)大的元素 被錯(cuò)誤地放到 數(shù)組的前面
            while(left < right && array[right] >= tmp) right--;
            while(left < right && array[left] <= tmp) left++;
            
            //此時(shí) left 和 right 分別指向 大于和小于 tmp的元素
            swap(array,left,right);
        }
        swap(array, i, right);
        return right;
    }

“挖坑”法

  1. 在待排序區(qū)間中,選取第一個(gè)元素作為基準(zhǔn)值 pivotkey ,用一個(gè)臨時(shí)變量 tmp 存儲(chǔ) pivotkey,同時(shí)定義 left 和 right 兩個(gè)“指針”,其中 left 指向待排序區(qū)間的第一個(gè)元素,right 指向待排序區(qū)間的最后一個(gè)元素。
    因基準(zhǔn)元素 pivot 的值已經(jīng)用 tmp 存儲(chǔ)起來(lái),故挖坑法顧名思義,已經(jīng)空出來(lái)的 pivot 位置就相當(dāng)于一個(gè)“坑”,當(dāng) right “指針” 找到比 pivotkey 小的元素時(shí),right 位置的元素可以直接“入坑”,與此同時(shí)right 位置就成為了一個(gè)新的“坑”;此時(shí) left “指針”開(kāi)始尋找比 pivotkey 大的元素,同樣 left 指向的元素“入到新坑”。
  2. 重復(fù)上述步驟,直到 left 和 right “指針”相遇,將 tmp 的值放入 兩“指針” 的相遇位置,此時(shí)分區(qū)操作完成。
  3. 將 pivot 左區(qū)間和右區(qū)間分為兩個(gè)新的待排序區(qū)間,重復(fù)1,2步驟,最終完成排序。

具體的排序過(guò)程如下圖所示:(數(shù)組的初始序列為:8,10,0,20,5,1,6,9)
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

“挖坑”法具體的代碼實(shí)現(xiàn)如下:

    public static void quickSort2(int[] array) {
        quick2(array, 0, array.length - 1);
    }
    private static void quick2(int[] tmpArray, int left, int right) {
        if(left >= right) return;       //代表此時(shí) 此時(shí)排序區(qū)間 只有一個(gè)元素 或者 排序區(qū)間不存在

        // 在 partition方法中,完成分區(qū)操作,并返回 pivot的下標(biāo)
        int pivot = partition2(tmpArray, left, right);
        // 對(duì) pivot 的左右區(qū)間進(jìn)行遞歸操作
        quick2(tmpArray, left, pivot - 1);
        quick2(tmpArray, pivot + 1, right);
    }
    private static int partition2(int[] tmpArray, int left, int right) {
        int tmp = tmpArray[left];
        while(left < right) {
            //必須先讓 right 去尋找比tmp小的元素, 因?yàn)檫@樣可以防止 一個(gè)大的元素 被錯(cuò)誤地放到 數(shù)組的前面
            while(left < right && tmpArray[right] >= tmp) right--;
            // right “指針” 入左坑
            swap(tmpArray, left, right);
            while(left < right && tmpArray[left] <= tmp) left++;
            // left “指針” 入右坑
            swap(tmpArray, left, right);
        }
        tmpArray[left] = tmp;
        return left;
    }

時(shí)間復(fù)雜度:O(n log n)。在數(shù)組原來(lái)有序的情況下(非遞減或非遞增),快速排序的遞歸過(guò)程會(huì)變成單分支樹(shù)的遞歸,退化成冒泡排序,即最壞情況下時(shí)間復(fù)雜度為O(n2);但平均時(shí)間復(fù)雜度仍為O(n log n)。
空間復(fù)雜度:O(1)。需要一個(gè)額外空間進(jìn)行元素交換或值存儲(chǔ)。
穩(wěn)定性:不穩(wěn)定。
適用情況:雖然快速排序存在退化成冒泡排序的可能性,但絕大多數(shù)情況下,數(shù)據(jù)均為亂序狀態(tài),因此快速排序可以稱(chēng)為“內(nèi)部排序”中最快的排序方法。

歸并排序

  • 基本算法思想:
    將兩個(gè)或兩個(gè)以上的有序表合并成一個(gè)有序表的過(guò)程稱(chēng)為歸并排序。將含有 n 個(gè)元素的待排序數(shù)組,看成是 n 個(gè)有序的子序列,每個(gè)子序列的長(zhǎng)度為1,接著將這 n 個(gè)子序列進(jìn)行兩兩歸并,得到 n/2(n/2+1) 個(gè)長(zhǎng)度為 2或1 的有序子序列;再將這 n/2 個(gè)有序子序列 進(jìn)行兩兩歸并,得到 n/4 個(gè)有序子序列……重復(fù)上述步驟,最終得到一個(gè)長(zhǎng)度為 n 的有序的序列,此時(shí)數(shù)組排序完成。

具體的排序過(guò)程如下圖所示:(數(shù)組的初始序列為:8,10,20,0,5,1,6)
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
從上圖不難看出,只要知道每次兩兩歸并時(shí),每個(gè)子數(shù)組的起始下標(biāo) start 和終點(diǎn)坐標(biāo) end ,我們即可根據(jù)學(xué)過(guò)的合并兩個(gè)有序列表的方法,最終將整個(gè)數(shù)組排列成有序序列。

那么如何將含 n 個(gè)元素的數(shù)組分成 n 個(gè)子序列,再進(jìn)行合并呢?
答案是:”采用“分而治之”的思想。先得到待排序數(shù)組中間元素的下標(biāo) mid ,將數(shù)組第一個(gè)元素的下標(biāo) start 到 mid 這個(gè)區(qū)間分為一個(gè)區(qū)間,將 mid+1 到 數(shù)組最后一個(gè)元素的下標(biāo) end 這個(gè)區(qū)間分為另一個(gè)區(qū)間。遞歸重復(fù)上述步驟,直到 start >= end,停止遞歸操作,開(kāi)始合并的過(guò)程。每次合并的左區(qū)間都為 start - mid,右區(qū)間為 mid+1 - end。

歸并排序具體的代碼實(shí)現(xiàn)如下:

    public static void mergeSort(int[] array) {
        merge(array, 0 , array.length - 1);
    }
    private static void merge(int[] array, int left, int right) {
        if(left >= right) return;

        //分解小區(qū)間
        int mid = (left + right) / 2;
        merge(array, left, mid);
        merge(array, mid + 1, right);

        //合并小區(qū)間的有序數(shù)組
        int start1 = left;
        int start2 = mid + 1;
        int[] mergeArray = new int[right - left + 1];
        int k = 0;
        while(start1 <= mid && start2 <= right) {
            if(array[start1] <= array[start2]) {
                mergeArray[k++] = array[start1++];
            }else {
                mergeArray[k++] = array[start2++];
            }
        }
        while(start1 <= mid) {
            mergeArray[k++] = array[start1++];
        }
        while(start2 <= right) {
            mergeArray[k++] = array[start2++];
        }
        //將mergeArray數(shù)組中的元素 放回到 原來(lái)數(shù)組的合并區(qū)間內(nèi)
        k = 0;
        while (left <= right) {
            array[left++] = mergeArray[k++];
        }
    }

時(shí)間復(fù)雜度:O(n log n)。
空間復(fù)雜度:O(n)。

基數(shù)排序

  • 算法基本原理:
    基數(shù)排序是一種非比較的排序方法,它通過(guò)若干次“分配”與“收集”對(duì)整個(gè)序列進(jìn)行排序?;鶖?shù)排序利用了“桶”的思想,需要將待排序元素“分解”成若干個(gè)關(guān)鍵字,并準(zhǔn)備若干個(gè)桶,使得桶的范圍能夠覆蓋每次關(guān)鍵字出現(xiàn)的所有可能情況,根據(jù)每個(gè)元素關(guān)鍵字的值依次放入對(duì)應(yīng)的桶,并將元素按桶的順序和元素放入的順序依次取出,進(jìn)行下次“分配”,直至所有關(guān)鍵字完成“分配”和“收集”。

例如:要對(duì)整數(shù)類(lèi)型的數(shù)組進(jìn)行排序,數(shù)組中的元素分別為:12,44,8,26,40,99,3,76,60,25。我們可以將每個(gè)元素的十位個(gè)位“分解”成2個(gè)關(guān)鍵字,因?yàn)槊總€(gè)關(guān)鍵字的范圍是0~9,因此我們每次需要先準(zhǔn)備10個(gè)桶,每個(gè)桶依次存放關(guān)鍵字為 0 ~ 9 的元素。
接著采用“最低位優(yōu)先法”,即先匹配個(gè)位這個(gè)關(guān)鍵字,將元素依次放入對(duì)應(yīng)的桶,按桶的順序和元素放入的順序依次取出后,接著“分配”并“收集”十位這個(gè)關(guān)鍵字,最終完成排序。(如下圖)
【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java

計(jì)數(shù)排序的具體代碼實(shí)現(xiàn)如下:

	public static void radixSort(int[] array) {
        // 1. 先獲得所有元素中的最大位數(shù)
        int count = 1;          // 記錄最大位數(shù)
        int multiple = 10;      // 記錄當(dāng)前倍數(shù)
        for (int x : array) {
            while (x / multiple > 0) {
                multiple *= 10;
                count++;
            }
        }

        // 2. 采用“最低位優(yōu)先法”進(jìn)行 count 次“分配”與“收集”
        multiple = 1;       // 描述當(dāng)前關(guān)鍵字的取值方式
        for (int i = 0; i < count; i++) {
            // 準(zhǔn)備 0~9,總共10個(gè)桶存放元素
            int[][] buckets = new int[10][0];
            for (int j = 0; j < 10; j++) {
                buckets[j] = new int[0];
            }
            // 針對(duì)關(guān)鍵字進(jìn)行“分配”
            for (int x : array) {
                int key = x / multiple % 10;
                int len = buckets[key].length;
                buckets[key] = Arrays.copyOf(buckets[key], len + 1);
                buckets[key][len] = x;
            }
            // 對(duì)元素按順序收集
            int k = 0;
            for (int j = 0; j < 10; j++) {
                // 遍歷每個(gè)桶
                for (int x : buckets[j]) {
                    array[k++] = x;
                }
            }
            multiple *= 10;
        }
    }

時(shí)間復(fù)雜度:O(d (n+t))。對(duì)于 n 個(gè)元素的序列(假設(shè)每個(gè)元素含有 d 個(gè)關(guān)鍵字,每個(gè)關(guān)鍵字的取值范圍有 t 個(gè)值),每一趟“分配”的時(shí)間復(fù)雜度為O(n),每一趟“收集”的時(shí)間復(fù)雜度為O(t),要進(jìn)行 d 趟“分配”與“收集”,因此總的時(shí)間復(fù)雜度為O(d (n+t))。
空間復(fù)雜度:O(n+d)。
穩(wěn)定性:穩(wěn)定。
適用情況:有較為苛刻的要求,需要知道各個(gè)關(guān)鍵字的主次關(guān)系和每個(gè)關(guān)鍵字的所有可能取值范圍。

計(jì)數(shù)排序

  • 算法基本思想:
  1. 遍歷待排序數(shù)組,記錄數(shù)組中的最大值 max 和最小值 min。
  2. 申請(qǐng)一個(gè)空間大小為 max-min+1 的計(jì)數(shù)數(shù)組,計(jì)數(shù)數(shù)組的下標(biāo)通過(guò)一定的轉(zhuǎn)換可以代表待排序數(shù)組的每個(gè)元素大小,鍵值記錄數(shù)字中每個(gè)元素出現(xiàn)的次數(shù)。對(duì)待排序數(shù)組進(jìn)行遍歷,統(tǒng)計(jì)每個(gè)元素出現(xiàn)的次數(shù)。
  3. 對(duì)計(jì)數(shù)數(shù)組進(jìn)行順序遍歷,假如數(shù)組中某元素的值 n 大于0,通過(guò)元素的下標(biāo),將 n 個(gè)轉(zhuǎn)換后的元素值放入到待排序數(shù)組中。待計(jì)數(shù)數(shù)組遍歷完畢,最終完成排序操作。

注意:計(jì)數(shù)數(shù)組下標(biāo) = array[i] - array[min]

待排序數(shù)組與計(jì)數(shù)數(shù)組的關(guān)系如下:【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明!?。。?數(shù)據(jù)結(jié)構(gòu),排序算法,java
具體代碼實(shí)現(xiàn)如下:

	public static void countSort(int[] array) {
        int minVal = array[0];
        int maxVal = array[0];
        // 找到數(shù)組元素的最大值和最小值
        for (int i = 1; i < array.length; i++) {
            if(array[i] < minVal) minVal = array[i];
            if(array[i] > maxVal) maxVal = array[i];
        }
        int[] countArray = new int[maxVal - minVal + 1];
        // 記錄每個(gè)元素出現(xiàn)的次數(shù)
        count(array, countArray , minVal);
        //把排序好的數(shù)據(jù)寫(xiě)回到 tmpArray 數(shù)組中
        int k = 0;
        for (int i = 0; i < countArray.length; i++) {
            while(countArray[i] > 0) {
                array[k++] = i + minVal;
                countArray[i]--;
            }
        }
    }
    private static void count(int[] array, int[] countArray, int minVal) {
        for (int i = 0; i < array.length; i++) {
            countArray[array[i] - minVal]++;
        }
    }

時(shí)間復(fù)雜度:O(n + k),計(jì)數(shù)的時(shí)間復(fù)雜度不僅數(shù)組元素的個(gè)數(shù) n 有關(guān),也取決于數(shù)組中最大和最小元素的區(qū)間 k。
空間復(fù)雜度:O(K)。(針對(duì)當(dāng)前代碼實(shí)現(xiàn)方式)
穩(wěn)定性:不穩(wěn)定。(針對(duì)當(dāng)前代碼實(shí)現(xiàn)方式)
適用情況:當(dāng)待排序數(shù)組數(shù)據(jù)量較大且數(shù)據(jù)分布較集中時(shí),計(jì)數(shù)排序的適用程度較高。當(dāng)數(shù)據(jù)分別較分散,差值很大時(shí)應(yīng)使用其他排序算法。


以上就是本篇文章的全部?jī)?nèi)容了,如果這篇文章對(duì)你有些許幫助,你的點(diǎn)贊、收藏和評(píng)論就是對(duì)我最大的支持。
另外,文章可能存在許多不足之處,也希望你可以給我一點(diǎn)小小的建議,我會(huì)努力檢查并改進(jìn)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-717509.html

到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)——9大基礎(chǔ)排序】一文掌握九大經(jīng)典排序(配有詳細(xì)圖文說(shuō)明?。。。┑奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)】一文帶你全面了解排序(上)——直接插入排序、希爾排序、選擇排序、堆排序

    【數(shù)據(jù)結(jié)構(gòu)】一文帶你全面了解排序(上)——直接插入排序、希爾排序、選擇排序、堆排序

    目錄 一、排序的概念及其運(yùn)用 1.1?排序的概念 1.2?常見(jiàn)的算法排序 二、常見(jiàn)排序算法的實(shí)現(xiàn) 2.1?插入排序 2.1.1?思想 2.1.2?直接插入排序 2.1.3?希爾排序(縮小增量排序)? 2.2?選擇排序 2.2.1?基本思想 2.2.2?直接選擇排序 2.2.3?堆排序? 沒(méi)有堅(jiān)持的努力實(shí)質(zhì)上并沒(méi)有太大的意義

    2024年02月16日
    瀏覽(95)
  • 數(shù)據(jù)結(jié)構(gòu)--》從線性表說(shuō)起,掌握常用基礎(chǔ)算法

    數(shù)據(jù)結(jié)構(gòu)--》從線性表說(shuō)起,掌握常用基礎(chǔ)算法

    目錄 初識(shí)線性表 線性表的基本操作 順序表的定義 順序表的基本操作 單鏈表的定義 單鏈表的基本操作? 雙鏈表的介紹 循環(huán)鏈表的介紹 靜態(tài)鏈表的介紹 線性表是具有 相同 數(shù)據(jù)類(lèi)型的 n (n0) 個(gè)數(shù)據(jù)元素的 有限序列 ,其中n為 表長(zhǎng) ,當(dāng)n=0時(shí)線性表是一個(gè) 空表 。若用L命名線性

    2024年02月09日
    瀏覽(21)
  • 數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之排序算法

    在數(shù)據(jù)結(jié)構(gòu)中,常見(jiàn)的排序算法有以下幾種: 冒泡排序(Bubble Sort):通過(guò)比較相鄰元素并交換它們的位置,每輪將最大(或最小)的元素冒泡到末尾,重復(fù)執(zhí)行直到排序完成。 特點(diǎn):簡(jiǎn)單易懂,但對(duì)于大型數(shù)據(jù)集效率較低。 時(shí)間復(fù)雜度: 最優(yōu)情況:O(n)(當(dāng)數(shù)組已經(jīng)排序好

    2024年02月15日
    瀏覽(25)
  • 【C++數(shù)據(jù)結(jié)構(gòu) | 圖速通】10分鐘掌握鄰接矩陣 & 鄰接表 | 快速掌握?qǐng)D論基礎(chǔ) | 快速上手抽象數(shù)據(jù)類(lèi)型圖

    【C++數(shù)據(jù)結(jié)構(gòu) | 圖速通】10分鐘掌握鄰接矩陣 & 鄰接表 | 快速掌握?qǐng)D論基礎(chǔ) | 快速上手抽象數(shù)據(jù)類(lèi)型圖

    by.Qin3Yu 請(qǐng)注意:嚴(yán)格來(lái)說(shuō),圖不是一種數(shù)據(jù)結(jié)構(gòu),而是一種抽象數(shù)據(jù)類(lèi)型。但為了保證知識(shí)點(diǎn)之間的相關(guān)性,也將其列入數(shù)據(jù)結(jié)構(gòu)專(zhuān)欄。 本文需要讀者掌握順序表和單鏈表的操作基礎(chǔ),若需學(xué)習(xí),可參閱我的往期文章: 【C++數(shù)據(jù)結(jié)構(gòu) | 順序表速通】使用順序表完成簡(jiǎn)單的成

    2024年02月05日
    瀏覽(26)
  • Java基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)之排序

    Java基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)之排序

    假定在待排序的記錄序列中,存在多個(gè)具有相同的的記錄,若經(jīng)過(guò)排序,這些記錄的相對(duì)次序保持 不變,即在原序列中, r[i]=r[j] ,且 r[i] 在 r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,則稱(chēng)這種排序算法是穩(wěn) 定的;否則稱(chēng)為不穩(wěn)定的。 內(nèi)部排序 :數(shù)據(jù)元素

    2024年01月25日
    瀏覽(25)
  • C++基礎(chǔ)-介紹·數(shù)據(jù)結(jié)構(gòu)·排序·算法

    C++是一門(mén)風(fēng)格嚴(yán)謹(jǐn)又不失自由的開(kāi)發(fā)語(yǔ)言,提供了完整的內(nèi)存管理、支持函數(shù)式編程和面向?qū)ο缶幊?,支持模板、多繼承、多實(shí)現(xiàn)、重載、重寫(xiě)等多態(tài)特性。 優(yōu)勢(shì)在于目前90%的操作系統(tǒng)、數(shù)據(jù)庫(kù)、應(yīng)用基礎(chǔ)架構(gòu)、硬件嵌入式等都是使用C/C++制作的,而C++是對(duì)C的標(biāo)準(zhǔn)擴(kuò)展,掌握

    2024年02月03日
    瀏覽(33)
  • 《數(shù)據(jù)結(jié)構(gòu)與算法》之十大基礎(chǔ)排序算法

    《數(shù)據(jù)結(jié)構(gòu)與算法》之十大基礎(chǔ)排序算法

    冒泡排序是一種交換排序,它的思路就是在待排序的數(shù)據(jù)中,兩兩比較相鄰元素的大小,看是否滿足大小順序的要求,如果滿足則不動(dòng),如果不滿足則讓它們互換。 然后繼續(xù)與下一個(gè)相鄰元素的比較,一直到一次遍歷完成。一次遍歷的過(guò)程就被成為一次冒泡,一次冒泡的結(jié)束

    2024年02月05日
    瀏覽(24)
  • 數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)(王卓)(28):排序概述(分類(lèi))、直接插入排序思路

    數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)(王卓)(28):排序概述(分類(lèi))、直接插入排序思路

    目錄 排序分類(lèi):(本章目錄) 按數(shù)據(jù)存儲(chǔ)介質(zhì):(學(xué)習(xí)內(nèi)容) 內(nèi)部排序: 外部排序: 按比較器個(gè)數(shù):(學(xué)習(xí)內(nèi)容) 串行排序: 并行排序: 按主要操作:(學(xué)習(xí)內(nèi)容、里面的排序都會(huì)重點(diǎn)學(xué)) 比較排序: 基數(shù)排序: 按輔助空間: 原地排序: 非原地排序: 按穩(wěn)定性: 穩(wěn)

    2023年04月26日
    瀏覽(31)
  • 數(shù)據(jù)結(jié)構(gòu)--》掌握數(shù)據(jù)結(jié)構(gòu)中的查找算法

    數(shù)據(jù)結(jié)構(gòu)--》掌握數(shù)據(jù)結(jié)構(gòu)中的查找算法

    ????????當(dāng)你需要從大量數(shù)據(jù)中查找某個(gè)元素時(shí),查找算法就變得非常重要。 ??????? 無(wú)論你是初學(xué)者還是進(jìn)階者,本文將為你提供簡(jiǎn)單易懂、實(shí)用可行的知識(shí)點(diǎn),幫助你更好地掌握查找在數(shù)據(jù)結(jié)構(gòu)和算法中的重要性,進(jìn)而提升算法解題的能力。接下來(lái)讓我們開(kāi)啟數(shù)據(jù)

    2024年02月08日
    瀏覽(31)
  • 數(shù)據(jù)結(jié)構(gòu) 隊(duì)列(一篇基本掌握)

    數(shù)據(jù)結(jié)構(gòu) 隊(duì)列(一篇基本掌握)

    ????????任其事必圖其效;欲責(zé)其效,必盡其方。——?dú)W陽(yáng)修;本篇文章主要寫(xiě)的是什么是隊(duì)列、以及隊(duì)列是由什么組成的和這些組成接口的代碼實(shí)現(xiàn)過(guò)程。( 大多細(xì)節(jié)的實(shí)現(xiàn)過(guò)程以注釋的方式展示請(qǐng)注意查看 ) ? ?話不多說(shuō)安全帶系好,發(fā)車(chē)?yán)?(建議電腦觀看) 。 附

    2024年02月12日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包