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

【數據結構與算法】十大經典排序算法-快速排序

這篇具有很好參考價值的文章主要介紹了【數據結構與算法】十大經典排序算法-快速排序。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??個人博客:www.hellocode.top
??Java知識導航:Java-Navigate
??CSDN:HelloCode.
??知乎:HelloCode
??掘金:HelloCode
?如有問題,歡迎指正,一起學習~~


快速排序(Quick Sort)是一種高效的排序算法,是對冒泡排序的優(yōu)化。它采用分治法(Divide and Conquer)的思想,將待排序序列不斷分割成較小的子序列,然后對每個子序列進行排序,最后合并得到有序的序列??焖倥判蛟诖蠖鄶登闆r下具有優(yōu)異的性能,是許多常見排序算法中最快的之一。

基本思想

【數據結構與算法】十大經典排序算法-快速排序,數據結構與算法,排序算法,java,算法

這里的動畫用大佬五分鐘學算法的圖,很清晰

  1. 選擇一個基準元素(pivot)作為參考點。
  2. 將所有比基準元素小的元素移到基準元素的左邊,將所有比基準元素大的元素移到基準元素的右邊。此過程稱為分區(qū)(partitioning)。
  3. 對基準元素左右兩邊的子序列遞歸地進行相同的快速排序,直到子序列的大小為1或0,表示子序列已經有序。

如上圖所示,快速排序的基本思想就是選取一個基準數,將基準數小的都放在左邊,大的都放在右邊,也就是每次循環(huán)都會確定出基準數應該在的正確位置。

代碼實現

對應在代碼層面,需要使用到遞歸法來實現,對于快速排序來說,遞歸相對還是很容易想到的

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月08日 21:14
 */
public class QuickSort {
    public static void quickSort(int[] arr) {
        // 特殊情況處理
        if (arr == null || arr.length == 0 || arr.length == 1) {
            return;
        }
        // 遞歸入口
        sort(arr, 0, arr.length - 1);
    }

    private static void sort(int[] arr, int left, int right) {
        // 遞歸出口
        if (left > right) {
            return;
        }
        // 初始化雙指針
        int i = left, j = right;
        // 選取基準數
        int base = arr[left];
        while (i != j) {
            // (注意?。。。。挠疫呴_始
            // 找比基準數小的
            while (i < j && arr[j] >= base) {
                j--;
            }
            // 從左邊找比基準數大的
            while (i < j && arr[i] <= base) {
                i++;
            }
            // 交換i j
            if (i < j) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        // 基準數歸位(此時i == j)
        arr[left] = arr[i];
        arr[i] = base;
        // 開始左右兩邊分別快排
        sort(arr, left, i - 1);
        sort(arr, i + 1, right);
    }
}

這里先移動j還是先移動i主要是需要看基準數選取的位置,如果選最左邊的數,就需要先移動j(確保i == j 時對應的值是小于基準數的,再把基準數和該數交換,符合排序規(guī)則)
如果選取的基準數是最右邊,則先移動i指針(確保 i == j 時對應的值是大于基準數的)

測試:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月08日 21:14
 */
public class Test {
    public static void main(String[] args) {
        int[] arr = {21, 13, 4, 10, 7, 65, 32, 15, 32, 19, 33, 65, 89, 72, 12};
        System.out.println("排序前:" + Arrays.toString(arr));
        QuickSort.quickSort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }
}

【數據結構與算法】十大經典排序算法-快速排序,數據結構與算法,排序算法,java,算法

優(yōu)化

快排的優(yōu)化主要需要關注基準數的選取,如果待排序數組整體偏降序,此時還選最左側的為基準數的話,效率就相對慢一些,所以選取一個好的基準數可以讓快排的效率更加穩(wěn)定~

主要的方法有以下幾種:

  1. 隨機選擇基準元素:選擇隨機的基準元素可以降低最壞情況的概率,進而提高算法性能。
  2. 三數取中法:在選取基準元素時,不是簡單地選取第一個或最后一個元素,而是選擇中間元素、第一個元素和最后一個元素中的中位數作為基準元素,也可以降低最壞情況的概率。

這里基準數的選取可以很巧妙,還有很多種其他方法,都可以降低最壞情況的發(fā)生,本文以三數取中法為例:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月08日 21:14
 */
public class QuickSort {
    public static void quickSort(int[] arr) {
        // 特殊情況處理
        if (arr == null || arr.length == 0 || arr.length == 1) {
            return;
        }
        // 遞歸入口
        sort(arr, 0, arr.length - 1);
    }

    private static void sort(int[] arr, int left, int right) {
        // 遞歸出口
        if (left > right) {
            return;
        }
        // 初始化雙指針
        int i = left, j = right;
        // 選取基準數
        getBase(arr, left, right);
        int base = arr[left];
        while (i != j) {
            // (注意!?。。。挠疫呴_始
            // 找比基準數小的
            while (i < j && arr[j] >= base) {
                j--;
            }
            // 從左邊找比基準數大的
            while (i < j && arr[i] <= base) {
                i++;
            }
            // 交換i j
            if (i < j) {
                swap(arr, i, j);
            }
        }
        // 基準數歸位(此時i == j)
        arr[left] = arr[i];
        arr[i] = base;
        // 開始左右兩邊分別快排
        sort(arr, left, i - 1);
        sort(arr, i + 1, right);
    }

    // 取三點中間值(最終會移動到left位置,這樣可以不改變原有代碼)
    private static void getBase(int[] arr, int left, int right) {
        // 這里可以防止溢出且使用 >> 效率相對能高一些
        // 等價于 (left + right) / 2
        int mid = left + ((right - left) >> 1);
        // 確保第一個元素最小
        if (arr[left] > arr[right]) {
            swap(arr, left, right);
        }
        // 確保最后一個元素最大
        if (arr[mid] > arr[right]) {
            swap(arr, mid, right);
        }
        // 確定mid就是中間值,交換到最左邊
        if (arr[left] < arr[mid]) {
            swap(arr, left, mid);
        }
        System.out.println("基準數為:" + arr[left]);
    }

    // 交換數組兩下標元素位置
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

測試:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月07日 21:02
 */
public class Test {
    public static void main(String[] args) {
        int[] arr = {21, 13, 4, 10, 7, 65, 32, 15, 32, 19};
        System.out.println("排序前:" + Arrays.toString(arr));
        BubbleSort.bubbleSortOptimized1(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }
}
排序前:[21, 13, 4, 10, 7, 65, 32, 15, 32, 19, 33, 65, 89, 72, 12]
基準數為:15
基準數為:7
基準數為:4
基準數為:12
基準數為:10
基準數為:13
基準數為:32
基準數為:21
基準數為:19
基準數為:32
基準數為:65
基準數為:33
基準數為:65
基準數為:72
基準數為:89
排序后:[4, 7, 10, 12, 13, 15, 19, 21, 32, 32, 33, 65, 65, 72, 89]

總結

優(yōu)點

  1. 高效性:快速排序是一種高效的排序算法,在大多數實際情況下,它的性能通常比其他常見排序算法(如冒泡排序、插入排序)更好。
  2. 原地排序:快速排序是原地排序算法,不需要額外的輔助空間,只需在原始數組上進行交換操作。

缺點

  1. 最壞情況下的性能:當待排序序列已經基本有序或完全逆序時,快速排序的時間復雜度退化為 O(n^2),導致性能下降。這是因為基準元素的選擇可能導致分區(qū)不平衡,使得分區(qū)操作不再能有效地減少問題規(guī)模。
  2. 不穩(wěn)定性:快速排序是一種不穩(wěn)定的排序算法,意味著相等元素的相對順序在排序后可能發(fā)生變化。這在某些情況下可能導致問題,特別是對于復雜對象的排序,需要額外的處理來保持穩(wěn)定性。

復雜度

  • 時間復雜度:快速排序的平均時間復雜度為O(n log n),最壞情況下為O(n^2)。
  • 空間復雜度:快速排序是原地排序算法,空間復雜度為O(log n)。

適用于處理大規(guī)模數據集的排序,尤其在平均情況下,快速排序的性能較優(yōu)。但在處理已經有序或近乎有序的數據集時,快速排序的性能可能會下降,這時候其他穩(wěn)定的排序算法可能更合適。文章來源地址http://www.zghlxwxcb.cn/news/detail-642592.html

到了這里,關于【數據結構與算法】十大經典排序算法-快速排序的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 《數據結構與算法》之十大基礎排序算法

    《數據結構與算法》之十大基礎排序算法

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

    2024年02月05日
    瀏覽(24)
  • 數據結構——排序算法之快速排序

    數據結構——排序算法之快速排序

    ? ??個人主頁: 日刷百題 系列專欄 : 〖C/C++小游戲〗 〖Linux〗 〖數據結構〗 ? 〖C語言〗 ?? 歡迎各位 → 點贊 ??+ 收藏 ??+ 留言 ??? ? ? 快速排序是Hoare于1962年提出的一種二叉樹結構的交換排序方法。 基本思想: 任取待排序元素序列中 的某元素作為基準值,按照

    2024年01月21日
    瀏覽(23)
  • 數據結構與算法:快速排序

    數據結構與算法:快速排序

    荷蘭國旗問題 想要理解快速排序,就先理解這個問題: [LeetCode75.顏色分類] 荷蘭國旗是由紅白藍三色組成的: 現在將其顏色打亂 然后根據一定的算法,將其復原為紅白藍三色,這就叫做荷蘭國旗問題。 在LeetCode的題目中,其將荷蘭國旗的三個顏色用0,1,2來表達,也就是說

    2024年01月15日
    瀏覽(24)
  • 【數據結構與算法】:選擇排序與快速排序

    【數據結構與算法】:選擇排序與快速排序

    ?? 個人主頁 : Quitecoder ?? 專欄 :數據結構與算法 我的博客即將同步至騰訊云開發(fā)者社區(qū),邀請大家一同入駐:騰訊云 歡迎來到排序的第二個部分:選擇排序與快速排序! 選擇排序是一種簡單直觀的比較排序算法。該算法的基本思想是在每一輪中選出當前未排序部分的最

    2024年03月17日
    瀏覽(25)
  • 數據結構與算法之快速排序

    快速排序 (Quick Sort),又稱劃分交換排序(partition-exchange sort),通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數

    2024年02月10日
    瀏覽(21)
  • 【數據結構】排序算法(二)—>冒泡排序、快速排序、歸并排序、計數排序

    【數據結構】排序算法(二)—>冒泡排序、快速排序、歸并排序、計數排序

    ?? 樊梓慕: 個人主頁 ??? 個人專欄: 《C語言》《數據結構》《藍橋杯試題》《LeetCode刷題筆記》《實訓項目》 ?? 每一個不曾起舞的日子,都是對生命的辜負 目錄 前言 1.冒泡排序 2.快速排序 2.1Hoare版 2.2占坑版 2.3前后指針版 2.4三數取中對快速排序的優(yōu)化 2.5非遞歸版 3.歸

    2024年02月08日
    瀏覽(34)
  • 【數據結構與算法】:非遞歸實現快速排序、歸并排序

    【數據結構與算法】:非遞歸實現快速排序、歸并排序

    ?? 個人主頁 : Quitecoder ?? 專欄 :數據結構與算法 上篇文章我們詳細講解了遞歸版本的快速排序,本篇我們來探究非遞歸實現快速排序和歸并排序 快速排序的非遞歸實現主要依賴于棧(stack)來模擬遞歸過程中的函數調用棧。遞歸版本的快速排序通過遞歸調用自身來處理子

    2024年03月24日
    瀏覽(25)
  • 【數據結構與算法】如何對快速排序進行細節(jié)優(yōu)化以及實現非遞歸版本的快速排序?

    【數據結構與算法】如何對快速排序進行細節(jié)優(yōu)化以及實現非遞歸版本的快速排序?

    君兮_的個人主頁 即使走的再遠,也勿忘啟程時的初心 C/C++ 游戲開發(fā) Hello,米娜桑們,這里是君兮_,國慶長假結束了,無論是工作還是學習都該回到正軌上來了,從今天開始恢復正常的更新頻率,今天為大家?guī)淼膬热菔强焖倥判虻膬纱髢?yōu)化和非遞歸實現 好了廢話不多說,開

    2024年02月08日
    瀏覽(27)
  • 【數據結構與算法】快速排序的三種實現方法

    【數據結構與算法】快速排序的三種實現方法

    ? 目錄 一.基本思想 二.Hoare法 動態(tài)演示 三.挖坑法 動態(tài)演示 四.前后指針法 動態(tài)演示 五.快速排序優(yōu)化 隨機下標交換法 三路取中法 六.快速排序的特性 任取待排序元素序列中的某元素作為 基準值 ,按照該排序碼將待排序集合 分割成兩子序列 , 左子序列中所有元素均小于基

    2023年04月09日
    瀏覽(31)
  • 【數據結構與算法】快速排序的非遞歸實現方法

    【數據結構與算法】快速排序的非遞歸實現方法

    ? 目錄 一.前言 二.非遞歸實現 如果數據量過大的話,不斷遞歸就會出現 棧溢出 的現象,這個時候你的代碼是沒問題的,但就是跑不起來,這個時候就要 把遞歸改成非遞歸 。 一般有兩種改法: 1.直接改,利用循環(huán)等; 2.借助棧的輔助。 而快速排序的非遞歸實現方法就需要

    2023年04月17日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領取紅包

二維碼2

領紅包