日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

快速排序的三种实现方法

發(fā)布時(shí)間:2024/4/18 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 快速排序的三种实现方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1.快速排序的思想
    • 2.基本實(shí)現(xiàn)
        • 2.1第一種排序
        • 2.2第二種排序
        • 2.3第三種排序(挖坑法)
        • 2.4代碼測試
    • 3.代碼優(yōu)化
    • 4.快速排序小結(jié)

1.快速排序的思想

快速排序的過程可以分為以下幾步:

  • 先找一個(gè)基準(zhǔn),將這個(gè)基準(zhǔn)賦值給臨時(shí)變量tmp中
  • 從后往前找第一個(gè)比基準(zhǔn)小的數(shù)據(jù)賦值到i位置
  • 從前往后找第一個(gè)比基準(zhǔn)大的數(shù)據(jù)賦值到j(luò)位置
  • 重復(fù)步驟1和步驟2直到i和j相遇,然后將tmp的值賦給i和j相遇的位置
  • 將基準(zhǔn)左邊和基準(zhǔn)右邊的數(shù)據(jù)繼續(xù)按照步驟1,2,3,4進(jìn)行,直到數(shù)據(jù)全部排完。
  • 2.基本實(shí)現(xiàn)

    2.1第一種排序

    首先找基準(zhǔn)值,然后cur標(biāo)記left,prev標(biāo)記cur-1,然后cur遍歷,分為兩個(gè)階段:第一個(gè)是cur沒找到比基準(zhǔn)值大的,prev和cur一直緊挨著。第二種是找到了,然后cur++,繼續(xù)遍歷,找到比基準(zhǔn)值小的,然后才讓++prev,此時(shí)prev和cur換一下位置,cur繼續(xù)遍歷,循環(huán)結(jié)束,最后right-1和++prev位置交換,放好基準(zhǔn)值的位置。

    int Partion1(int* array, int left, int right) {int cur = left;int prev = cur - 1;int key = array[right - 1];while (cur < right){if (array[cur] < key && ++prev != cur)Swap(&array[cur], &array[prev]);cur++;}if (++prev != (right - 1))Swap(&array[prev], &array[right - 1]);return prev; }

    2.2第二種排序

    先標(biāo)記基準(zhǔn)值(這里先取最后一個(gè)元素為基準(zhǔn)值,記錄起來),之后定義兩個(gè)指針,然后前后遍歷,找到比基準(zhǔn)值大的或者小的的元素的位置,然后進(jìn)行標(biāo)記,標(biāo)記成功后進(jìn)行交換,最后添加一個(gè)循環(huán),此時(shí)的begin和end是在一個(gè)位置的,你要將begin和right-1(其實(shí)就是基準(zhǔn)值的位置)位置的元素交換。

    int Partion2(int* array, int left, int right) {int begin = left;int end = right - 1;//設(shè)置基準(zhǔn)值,取數(shù)組最右側(cè)的元素int key = array[end];while (begin < end){//尋找大于基準(zhǔn)值的數(shù)while (begin < end && array[begin] <= key)begin++;while (begin < end && array[end] >= key)end--;if (begin < end)Swap(&array[begin], &array[end]);}//這里將基準(zhǔn)值和begin(end)交換if (begin != right - 1)Swap(&array[begin], &array[right - 1]);return begin;//此時(shí)應(yīng)該返回begin,key只是值(這里是下標(biāo)操作) }

    2.3第三種排序(挖坑法)

    這種還是先標(biāo)記基準(zhǔn)值,依舊是begin和end兩個(gè)指針,然后begin先找比基準(zhǔn)值大的元素,將其填寫到right-1的位置上,此時(shí)的begin的位置就是一個(gè)坑,然后end從后開始遍歷,找到比基準(zhǔn)值小的元素將其填寫到begin的位置,end的位置就是一個(gè)坑,循環(huán)以上操作,結(jié)束后就將標(biāo)記起來的基準(zhǔn)值填寫到begin(end)的位置。

    int Partion3(int* array, int left, int right) {int begin = left;int end = right - 1;int key = array[end];//基準(zhǔn)值while (begin < end){//從頭開始大于key的值的位置while (begin < end && array[begin] <= key)begin++;//將這個(gè)值填到基準(zhǔn)值的位置if (begin < end){array[end--] = array[begin];//這里的end一定要往前走一步}//從尾開始大于key的值得位置while (begin < end && array[end] >= key)end--;//填坑在begin的位置if (begin < end){array[begin++] = array[end];}}//將基準(zhǔn)值填寫到begin的位置(此時(shí)的begin和end的位置是一樣的)array[begin] = key;return begin; }

    2.4代碼測試

    void Swap(int *left, int* right) {int temp = *left;*left = *right;*right = temp; }void QuickSort(int* array, int left, int right) {//right-left>1說明中間必有元素if (right - left > 1){int div = Partion3(array, left, right);QuickSort(array, left, div);QuickSort(array, div + 1, right);} }void Print(int* array, int size) {for (int i = 0; i < size; i++){printf("%d ", array[i]);}printf("\n"); }#include "QuickSort.h"int main() {int array[] = { 9, 3, 8, 6, 7, 2, 1, 0, 4, 5 };Print(array, sizeof(array) / sizeof(array[0]));QuickSort(array, 0, sizeof(array) / sizeof(array[0]));Print(array, sizeof(array) / sizeof(array[0]));return 0; }

    3.代碼優(yōu)化

    當(dāng)最右邊的數(shù)字是最大或者最小時(shí),此時(shí)我們對取基準(zhǔn)值進(jìn)行優(yōu)化,保證不至于偏差非常大。

    //三值取中法 int GetIndexOfMid(int* array, int left, int right) {int mid = left + ((right - left) >> 1);if (array[left] > array[right - 1]){if (array[mid] > array[left])return left;else if (array[mid] < array[right - 1])return right;elsereturn mid;}else{if (array[mid] < array[left])return left;else if (array[mid] > array[right - 1])return right;elsereturn mid;} }

    注意:三值取中法返回的是下標(biāo)。

    此時(shí)就需要優(yōu)化一下里面的三種排序里面的代碼。

    int ret = GetIndexOfMid(array, left, right);int key = array[ret];//基準(zhǔn)值//將那個(gè)放到最后面,就可以和之前的代碼連接起來Swap(&array[ret], &array[right - 1]);

    4.快速排序小結(jié)

    • 這個(gè)快排的時(shí)間復(fù)雜度為O(nlogn),空間復(fù)雜度為O(logn),快速排序是一個(gè)不穩(wěn)定的排序算法。

    • 若對于一系列有序(不論是遞增有序還是遞減有序)的數(shù)據(jù)進(jìn)行快排時(shí),快排就會(huì)退化,相當(dāng)于冒泡排序,解決方法主要有兩種,一種是隨機(jī)找一個(gè)基準(zhǔn),另外一種是三位數(shù)取中的方法。

    • 需要注意的是對于單鏈表中的數(shù)據(jù)不能用快速排序進(jìn)行,由于單鏈表只有一個(gè)后繼指針而沒有前驅(qū)指針,因此單鏈表是不能用快排進(jìn)行排序的。

    • 當(dāng)數(shù)據(jù)量比較大的時(shí)候不適合用快速排序,此時(shí)堆排序?qū)@些數(shù)據(jù)進(jìn)行排序更為合適。

    總結(jié)

    以上是生活随笔為你收集整理的快速排序的三种实现方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。