排序演算法(四)、選擇排序 —— 簡單選擇排序 和 堆排序
阿新 • • 發佈:2018-12-30
1、簡單選擇排序
簡單選擇排序思想是:從頭到尾(從後往前也行)遍歷序列,先固定第一個位置的資料,將該位置後面的資料,依次和這個位置的資料進行比較,如果比固定位置的資料大,就交換。這樣,進行一趟排序以後,第一個位置就是最小的數了。然後重複進行,第 2 次遍歷並且比較後,第二個位置就是第二小的數字了,,依次類推
比較簡單,直接上程式碼吧:
void selectsort(int a[], int n) { for (int i = 0; i < n-1; i++) { int min = i; // 保留一份開始下標的副本 for (int j = i + 1; j < n; j++) // 從該值後面的資料開始遍歷 { if (a[j] < a[min]) min = j; } if (i != min) swap(a[i],a[min]); // 第 i 個位置就是這一輪最小的數字了 } }
2、堆排序
堆排序的原理不贅述了,不太明白的同學可以參考連結:堆與堆排序
下面,說一下利用 STL 實現堆排序。
STL中與堆相關的4個函式——建立堆make_heap(),在堆中新增資料push_heap(),在堆中刪除資料pop_heap()和堆排序sort_heap():
標頭檔案 #include <algorithm>
下面的_First與_Last為可以隨機訪問的迭代器(指標),_Comp為比較函式(仿函式),其規則——如果函式的第一個引數小於第二個引數應返回true,否則返回false。
(1)、建立堆
make_heap(_First, _Last, _Comp)
預設是建立最大堆的
push_heap (_First, _Last)
要先在容器中加入資料,再呼叫push_heap ()
(3)、在堆中刪除資料pop_heap(_First, _Last)
要先呼叫pop_heap()再在容器中刪除資料
(4)堆排序
sort_heap(_First, _Last)
排序之後就不再是一個合法的heap了
例項如下:
bool comp(int a,int b) // 建立一個最小堆 { if (a > b) return true; return false; } int main() { vector<int> v_heap; v_heap.push_back(3); v_heap.push_back(7); v_heap.push_back(31); v_heap.push_back(4); v_heap.push_back(12); v_heap.push_back(7); v_heap.push_back(24); v_heap.push_back(9); make_heap(v_heap.begin(), v_heap.end(),comp); // 這個 comp 是對應的,如果建立堆得時候有,排序的時候也要有 //v_heap.push_back(5); // 應該先往容器中新增資料,然後再呼叫 push_heap() 往堆中加入資料 //push_heap(v_heap.begin(),v_heap.end(),comp); pop_heap(v_heap.begin(),v_heap.end(),comp);// 需要先呼叫 pop_heap(),才能在容器中刪除資料 v_heap.pop_back(); // 刪除最後一個數據 for (auto v : v_heap) cout << v <<" "; cout << endl; //sort_heap(v_heap.begin(),v_heap.end(),comp);// 如果建立的是最大堆,排序後的結果就是從小到大。最小堆排序後的結果是從大到小 //for (auto v : v_heap) // cout << v << " "; //cout << endl; return 0; }
這裡說明一下幾個問題:
(1)make_heap() 函式,建立堆得過程實際上也是一種排序的過程,只不過這種排序,不是嚴格意義上的從大到小排序
(2)sort_heap() 函式以後,排序得到的結果已經不再是一個堆了
(3)如果是對一個數組進行堆操作,pop_head() 函式,是將第一個元素放到最後一個,然後將剩下的元素重新建立堆。
堆排序有很多應用,有一題詳見下一篇部落格