1. 程式人生 > >排序演算法(四)、選擇排序 —— 簡單選擇排序 和 堆排序

排序演算法(四)、選擇排序 —— 簡單選擇排序 和 堆排序

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)

預設是建立最大堆的

。對int型別,可以在第三個引數傳入greater<int>()得到最小堆。

(2)、在堆中新增資料
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() 函式,是將第一個元素放到最後一個,然後將剩下的元素重新建立堆。

堆排序有很多應用,有一題詳見下一篇部落格