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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[数据结构]快速排序

發(fā)布時間:2025/3/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [数据结构]快速排序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、問題描述

內(nèi)部排序是一件具有重大意義的問題,許多項目的實現(xiàn)中都需要用到排序。

我們知道,排序的算法有許多種,每種排序算法的時間復(fù)雜度和空間復(fù)雜度不盡相同。在解決實際問題時,往往需要根據(jù)實際需要選擇排序算法。

上次實驗已經(jīng)討論了希爾排序的實現(xiàn)及其原理,本實驗重點介紹另一種排序算法——快速排序。實驗中將討論快速排序的實現(xiàn)及其原理。

二、數(shù)據(jù)結(jié)構(gòu)——順序結(jié)構(gòu)

本實驗重點在算法實現(xiàn)上,數(shù)據(jù)結(jié)構(gòu)的思想被弱化了。在排序過程中,由于維護(hù)序關(guān)系的需要,要有交換的操作,這就破壞了ADT的物理位置的相鄰反映邏輯的依次的性質(zhì),可以說這里的順序結(jié)構(gòu)只是一個二次結(jié)構(gòu)。因此,本實驗不對此作過多說明。

三、算法的設(shè)計和實現(xiàn)

1、算法描述

快速排序是一種基于比較的排序算法,算法是不穩(wěn)定的。有一種形象的叫法是“挖坑+分治”排序來形容快速排序。以下簡要說明其操作。

以不降序排序為例。選擇序列中一個元素作為基準(zhǔn)元素,本實驗中選擇的是序列區(qū)間的第一個元素。定義兩個指針(這里的指針只是一個意指,不一定用c++語言中真正的指針來實現(xiàn),可以是一個整型數(shù))i和j,初始時分別指向待排序列區(qū)間的首、尾。

每一輪排序時,選擇第一個元素作為基準(zhǔn)元素,相當(dāng)于在序列區(qū)間的第一個位置挖了一個坑,現(xiàn)在要填坑。移動j,直到Elem[j]比基準(zhǔn)元素小,將Elem[j]挖出來填到第一個位置,這時坑就是j這個位置了;移動i,知道Elem[i]比基準(zhǔn)元素大,將Elem[i]挖出來填到j(luò)位置,這時坑就是i這個位置了。重復(fù)上述挖坑、填坑的操作,直到i == j,結(jié)束循環(huán)。此時,將基準(zhǔn)元素填入當(dāng)前的坑里,于是在該基準(zhǔn)元素的左側(cè)的元素都比它小,右側(cè)的都比它大。這時就出現(xiàn)了一個自相似的子結(jié)構(gòu),于是很自然地選擇遞歸,將當(dāng)前的待排序序列區(qū)間以基準(zhǔn)元素的位置一分為二,分別重復(fù)上述過程。遞歸的邊界是當(dāng)前區(qū)間只有一個元素,平凡有序。

所謂“挖坑”上面已經(jīng)提到了,所謂“分治”就是指的區(qū)間一分為二的遞歸過程。

2、算法復(fù)雜度分析

快速排序的時間主要耗費在劃分操作上,設(shè)當(dāng)前待排序區(qū)間長度為k,則共需要k-1次關(guān)鍵字的比較。

最壞情況是每次劃分選取的基準(zhǔn)元素都是當(dāng)前區(qū)間的最小(或者最大)元素,那么劃分的結(jié)果將是左邊的子區(qū)間(或者右邊的子區(qū)間)為空,而右邊的子區(qū)間(或者左邊的子區(qū)間)長度為k-1,僅比之前少一個元素。此時的時間復(fù)雜度為O(n^2)。

最好情況是每次劃分選取的基準(zhǔn)元素都正好是當(dāng)前區(qū)間的中位數(shù),劃分的結(jié)果是左、右子區(qū)間元素個數(shù)大致相等,總的復(fù)雜度為O(n lgn)。

盡管快速排序的最壞情況復(fù)雜度逼近平方級別,但就平均性能而言,它是基于關(guān)鍵字比較的內(nèi)部排序算法中速度最快的(這個網(wǎng)上有許多算法的時間測試,這里不再贅述),它的平均時間復(fù)雜度為O(n lgn)。

3、例子

(1)第一輪

基準(zhǔn)元素下標(biāo)12345678910
727265788604283734885
?4865788604283734885
?4865788604283738885
?4865742604283738885
?4865742607283738885

(2)第二輪

a)區(qū)間[1,5]

基準(zhǔn)元素下標(biāo)12345
48486574260
?426574260
?426575760
?426485760

b)區(qū)間[7,10]

基準(zhǔn)元素下標(biāo)78910
8383738885
?73738885
?73838885

c)總的序列

4264857607273838885

(3)第三輪

a)區(qū)間[1,2]

基準(zhǔn)元素下標(biāo)12
42426
?66
?642

b)區(qū)間[4,5]

基準(zhǔn)元素下標(biāo)45
575760
?5760

c)區(qū)間[7,7],直接返回

d)區(qū)間[9,10]

基準(zhǔn)元素下標(biāo)910
888885
?8585
?8588

e)總的序列

6424857607273838588

排序完成

四、預(yù)期結(jié)果和實驗中的問題

1、預(yù)期結(jié)果

程序能夠正確地將一個序列按照不遞減的順序排序。下圖為一個例子。

2、實驗中的問題及思考

快速排序還有一些改進(jìn)的版本,當(dāng)然比較常見的是在選擇基準(zhǔn)元素的時候采用隨機(jī)選擇的方式。據(jù)研究表明,選擇黃金分割點處的數(shù)作為基準(zhǔn)元素的期望速度最快,這個我還沒有仔細(xì)學(xué)習(xí)過。

附:c++源代碼:

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 #define MaxN 120 7 8 int gap[200]; //步長 2^k+1 第一項改為1 9 int n; 10 11 template <class T> class My_list 12 { 13 private: 14 T Elem[MaxN]; //待排序的元素 15 int Len; //元素個數(shù) 16 public: 17 void Init() 18 { 19 memset(Elem, 0, sizeof(Elem)); 20 Len = 0; 21 } 22 void Insert_back(T x) 23 { 24 Elem[++Len] = x; 25 } 26 void Print() 27 { 28 int i; 29 for(i = 1; i < Len; i++) 30 printf("%d ", Elem[i]); 31 printf("%d\n", Elem[i]); 32 } 33 int GetLen() 34 { 35 return Len; 36 } 37 void QuickSort(int st, int ed) 38 { 39 if(st < ed) 40 { 41 int i = st, j = ed, x = Elem[st]; 42 while(i < j) 43 { 44 while(i < j && Elem[j] > x) //找右側(cè)比x大的元素 45 j--; 46 if(i < j) 47 Elem[i++] = Elem[j]; 48 while(i < j && Elem[i] < x) //找左側(cè)比x小的元素 49 i++; 50 if(i < j) 51 Elem[j--] = Elem[i]; 52 } 53 Elem[i] = x; 54 QuickSort(st, i - 1); //分治左側(cè)區(qū)間 55 QuickSort(i + 1, ed); //分治右側(cè)區(qū)間 56 } //if 57 } 58 }; 59 60 void Read(My_list <int> &L) 61 { 62 int i, x; 63 L.Init(); 64 printf("請輸入需要排序的數(shù)的個數(shù)。\n"); 65 scanf("%d", &n); 66 printf("請輸入需要排序的數(shù)列。\n"); 67 for(i = 1; i <= n; i++) 68 { 69 scanf("%d", &x); 70 L.Insert_back(x); //把x插入到最后 71 } 72 } 73 74 int main() 75 { 76 int GapNum; 77 My_list <int> L; 78 Read(L); 79 L.QuickSort(1, n); 80 printf("升序排序后的數(shù)列:\n"); 81 L.Print(); 82 return 0; 83 } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/CQBZOIer-zyy/p/5185409.html

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的[数据结构]快速排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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