《王道》第15章 排序 PART2

2021-08-18 18:17:45 字數 3365 閱讀 7186

目錄

3 選擇排序

3.1 簡單選擇排序

基本思想

演算法實現

演算法分析

3.2 堆排序

基本思想

演算法實現

演算法分析

演算法應用——top k問題

選擇排序基本思想:每一趟在n - i + 1(i = 1,2,…n - 1)個記錄中選取關鍵字最小的記錄作為有序序列中第i個記錄。

選擇排序引申出簡單選擇排序和堆排序。

第1趟,在待排序記錄r[1]~r[n]中選出最小的記錄,將它與r[1]交換;第2趟,在待排序記錄r[2]~r[n]中選出最小的記錄,將它與r[2]交換;以此類推,第i趟在待排序記錄r[i]~r[n]中選出最小的記錄,將它與r[i]交換,使有序序列不斷增長直到全部排序完畢。

以下為簡單選擇排序的儲存狀態,其中大括號內為無序區,大括號外為有序序列:

初始序列:

第1趟:12與49交換:12

第2趟:27不動 :12 27

第3趟:65與38交換:12 27 38

第4趟:97與49交換:12 27 38 49

第5趟:76與65交換:12 27 38 49 65

第6趟:97與76交換:12 27 38 49 65 76 97 完成

#include#include using namespace std;

void selectsort(int *a, int n)

if (min != i) //如果最小元素不是無序組起始位置元素,則與起始元素交換位置

swap(a[i], a[min]); }}

int main()

; int i = 0;

selectsort(a, 6); //這裡需要將數列元素個數傳入。可用sizeof在函式內求得元素個數。

for (i = 0; i < 6; i++)

system("pause");

return 0;

}

由於要選出最小值,故無序區中的每個元素都要參與比較,所以無論初始資料序列的狀態如何,總的比較次數為:

c = n - 1 + n - 2 + n - 3 + … + 2 + 1 = n(n - 1) / 2

故任何時候直接選擇排序的時間複雜度為o(n ^ 2),空間複雜度為o(1)。

直接選擇排序是乙個不穩定的演算法。例如,排序序列為,第一趟排序後得到,兩個5的相對位置發生了變化。

參考部落格

堆排序就是利用堆(假設利用大頂堆)進行排序的方法。它的基本思想是,將待排序的序列構成乙個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它移走(其實就是將其與堆陣列的末尾元素交換,此時末尾元素就是最大值),然後將剩餘的n-1個序列重新構造成乙個堆,這樣就會得到n個元素中的次大值。如此反覆執行,便能得到乙個有序序列了。

#include using namespace std;

// 函式adjustdown將元素k向下進行調整,堆主要的兩個函式之一

/* a為序列,start為初始下標,end為終止下標

*/void heapadjust(int *a, int start, int end)

if (temp > a[i])

else

} a[start] = temp; //將篩選結點的值放入最終位置

}//堆排序演算法

void heapsort(int *a, int len)

for (i = len-1; i > 0; i--)

}

時間複雜度  o(nlog2n),在最好、最壞和平均情況下,堆排序的時間複雜度為o(nlog2n)

空間複雜度  o(1),僅使用了常數個輔助單元

穩定性:不穩定

另外,由於初始構建堆所需的比較次數比較多,因此,它並不適合待排序序列個數較少的情況。 

如果要選出前k大,則將資料中的前k個元素建立成乙個小根堆,從第k + 1個元素開始往後依次比較,如果元素大於小根堆的堆頂,那麼就和堆頂交換,交換後重新調整為小根堆。這樣變數一遍所有資料,最後得到的大小為k的小根堆就是前k大的樹。

如果要選出前k小,則將資料中的前k個元素建立成乙個大根堆,從第k + 1個元素開始往後依次比較,如果元素小於小根堆的堆頂,那麼就和堆頂交換,交換後重新調整為大根堆。這樣變數一遍所有資料,最後得到的大小為k的大根堆就是前k小的樹。

以選出前k小的數為例,**:

#include using namespace std;

int main()

; //儲存輸入的n個數

int len = sizeof(data) / sizeof(int);

int k;

cin >> k;

if (k>len || k <= 0)

return;

int *b = new int[k];

for (int i = 0; ib[0])

continue;

else

}for (int i = 0; i4 排序總結

參考部落格1

參考部落格2

關於排序你應該知道的

ps:更正下表錯誤:簡單選擇排序不穩定

1)穩定性

所有簡單排序(時間複雜度為o(n^2))都是穩定排序,簡單選擇排序除外;

所有改進排序都是不穩定排序,歸併排序除外。

2)比較次數

比較次數與初始排列無關的是選擇排序。

在初始序列基本有序的情況下,最優的是直接插入排序,此時時間複雜度o(n),其次是氣泡排序,時間複雜度也為o(n),快速排序在此時效能最差,時間複雜度o(n^2)。

同時,快速排序在初始序列逆序的時候,效能也最差,此時時間複雜度也為o(n^2)。

堆排序對初始資料集的排列順序不敏感,在最好、最壞和平均情況下,堆排序的時間複雜度均為o(nlog2n)。

3)空間複雜度

基於比較的排序演算法中,歸併排序的空間複雜度最高,為o(n),其次為快速排序,為o(logn),其餘為o(1)。

4)時間複雜度

基於比較的排序演算法時間複雜度下界為o(nlog2n)。

第七章 滑鼠part2

7.5攔截滑鼠 乙個視窗訊息處理程式通常只在滑鼠游標位於視窗的顯示區域,或非顯示區域上時才接收滑鼠訊息。所以應該只有當滑鼠按鍵在您的顯示區域中被按下時才攔截滑鼠 當滑鼠按鍵被釋放時,才釋放滑鼠攔截。攔截滑鼠並非只適用於那些古怪的應用程式。如果您需要滑鼠按鍵在顯示區域按下時都能夠追蹤wm mousem...

第四章 輸出文字part2

4.4建立更好的滾動 win32 api介紹的兩個滾動條函式稱作setscrollinfo和getscrollinfo。這些函式可以完成以前函式的全部功能,並增加了兩個新特性。setscrollinfo hwnd,ibar,si,bredraw getscrollinfo hwnd,ibar,si ...

第四章 不定積分 part2

分段函式做不定積分 需要確保在分界點上,f x 的原函式是連續的,只要保證了f x 是連續的,f x 積分出來一定是可導並且求導等於f x 找到c1和c2之間的關係,然後統一表示出來 第五章 定積分與反常積分 第一節 定積分 考試概要 定積分概念 定積分性質 變上限積分函式 定積分的計算 二 常考題...