目錄
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之間的關係,然後統一表示出來 第五章 定積分與反常積分 第一節 定積分 考試概要 定積分概念 定積分性質 變上限積分函式 定積分的計算 二 常考題...