1. 程式人生 > >資料結構與演算法總結——常見排序演算法(未完待續)

資料結構與演算法總結——常見排序演算法(未完待續)

  • 本文包含的排序演算法
    • 氣泡排序
    • 插入排序
    • 選擇排序
    • 歸併排序
    • 快速排序
    • 希爾排序
    • 堆排序
    • 桶排序
    • 基數排序
  • 本文關於C++ 的知識點
  • 儘量使用vector代替陣列
  • 儘量使用std::move代替傳值
  • ++i 比 i++ 更高效,後者需要複製出一個臨時副本來完成當前操作
  • comparator(比較器),當資料型別本身不支援比較(如自定義類),而你又不想改變這個資料型別本身,於是需要從外部傳入一個比較類。為了簡化書寫,我們使用比較類的operator()函式來實現比較,具體可見main函式
//main.cpp

#include <iostream>
#include <string>
#include "BST.cpp"
#include "sort.cpp"

using namespace std;

class Obj
{
public:
	Obj() :
		s("0") {}
	Obj(string && str) :
		s(str) {}

	string s;
};

class Cmp
{
public:
	int operator() (const Obj & a, const Obj & b)
//具體比較方法可以自定義 { if (a.s.at(0) < b.s.at(0)) return 1; else return 0; } }; int main(int argc, char* argcv[]) { vector<Obj> arr = { Obj("a"), Obj("c"), Obj("b"), Obj("h"), Obj("j"), Obj("e"), Obj("d")}; Sort<Obj, Cmp> sort; sort.merge(arr);//可替代為別的演算法 for (Obj x : arr) cout <<
x.s << endl; return 0; }
#ifndef SORT_H
#define SORT_H
#include <iostream>
#include <functional>
#include <vector>
using namespace std;

template <typename Object, typename Comparator = less<Object>>//預設為呼叫<functional>中的less比較函式
class Sort 
{
public:

	void bubble(vector<Object> & arr);
	void insert(vector<Object> & arr);
	void select(vector<Object> & arr);
	void merge(vector<Object> & arr);
	void quick(vector<Object> & arr);
	void shell(vector<Object> & arr);
	void heap(vector<Object> & arr);
	void bucket(vector<Object> & arr);
	void radix(vector<Object> & arr);

private:
	Comparator lessThan;

	void swap(Object & a, Object & b);
	void merge(vector<Object> & arr,size_t low, size_t high, vector<Object> & tempArr);
	void mergeHelper(vector<Object> & arr, size_t low, size_t mid, size_t high, vector<Object> & tempArr);
	void quick(vector<Object> & arr, size_t low, size_t high);
	size_t partition(vector<Object> & arr, size_t low, size_t high); 

};

#endif // !SORT_H


#include "sort.h"

//升序排列

template <typename Object, typename Comparator>
void Sort<Object, Comparator>::bubble(vector<Object> & arr)
{
	for (size_t i = arr.size() - 1; i > 0 ; --i)
		for (size_t j = 0; j < i; ++j)
			if (lessThan(arr.at(j + 1), arr.at(j)))
				swap(arr.at(j + 1), arr.at(j));
}

template <typename Object, typename Comparator>
void Sort<Object, Comparator>::insert(vector<Object> & arr)
{
	for (size_t i = 1; i < arr.size(); ++i)
	{
		auto temp = std::move(arr.at(i));
		size_t j = i;// j不能初始化為i - 1
		for (; j > 0 && lessThan(temp, arr.at(j - 1)); --j)//可以將判斷條件移至迴圈頭
				arr.at(j) = std::move(arr.at(j - 1));

		arr.at(j) = std::move(temp);
	}
}

template <typename Object, typename Comparator>
void Sort<Object, Comparator>::select(vector<Object> & arr)
{
	for (size_t i = 1; i < arr.size() - 1; ++i)
	{
		auto offset = i;
		for (size_t j = i + 1; j < arr.size(); ++j)
		{
			if (lessThan(arr.at(j), arr.at(offset)))
				offset = j;
		}
		swap(arr.at(i), arr.at(offset));
	}
}

template <typename Object, typename Comparator>
void Sort<Object, Comparator>::merge(vector<Object> & arr)
{
	vector<Object> tempArr(arr.size());
	merge(arr, 0, arr.size() - 1, tempArr);
}

template <typename Object, typename Comparator>
void Sort<Object, Comparator>::quick(vector<Object> & arr)
{
	vector<Object> tempArr(arr.size());
	quick(arr, 0, arr.size() - 1);
}

/*


private


*/


template <typename Object, typename Comparator>
void Sort<Object, Comparator>::quick(vector<Object> & arr, size_t low, size_t high)
{
	if (low >= high)
		return;

	size_t position = partition(arr, low, high);
	quick(arr, low, position - 1);
	quick(arr, position + 1, high);
}

template <typename Object, typename Comparator>
size_t Sort<Object, Comparator>::partition(vector<Object> & arr, size_t low, size_t high)
{
	size_t shuffle = low + rand() % (high - low + 1);
	swap(arr.at(low), arr.at(shuffle));
	auto par = arr.at(low);
	size_t i = low + 1, j = high; //注意i初始值為low + 1

	while (true)
	{
		while (lessThan(arr.at(i), par))
			++i;
		while (lessThan(par, arr.at(j)))
			--j;
		if (i >= j) //應該在這裡判斷,而不是while迴圈頭
			break;

		swap(arr.at(i), arr.at(j));
	}
	swap(arr.at(low), arr.at(j));
	return j;
}

template <typename Object, typename Comparator>
void Sort<Object, Comparator>::merge(vector<Object> & arr, size_t low, size_t high, vector<Object> & tempArr)
{
	if (low >= high)
		return;

	size_t mid = (low + high) / 2;

	merge(arr, low, mid, tempArr);
	merge(arr, mid + 1, high, tempArr);
	mergeHelper(arr, low, mid, high, tempArr);
}



template <typename Object, typename Comparator>
void Sort<Object, Comparator>::mergeHelper(vector<Object> & arr, size_t low, size_t mid, size_t high, vector<Object> & tempArr)
{
	size_t i = low, j = mid + 1;
	for (size_t k = low; k <= high; ++k)
	{
		if (i > mid)
			tempArr.at(k) = std::move(arr.at(j++));
		else if (j > high)
			tempArr.at(k) = std::move(arr.at(i++));
		else if (lessThan(arr.at(i), arr.at(j)))
			tempArr.at(k) = std::move(arr.at(i++));
		else
			tempArr.at(k) = std::move(arr.at(j++));
	}

	for (size_t p = low; p <= high; p++)
		arr.at(p) = std::move(tempArr.at(p));
}


template <typename Object, typename Comparator>
void Sort<Object, Comparator>::swap(Object & a, Object & b)
{
	auto temp = std::move(b);
	b = std::move(a);
	a = std::move(temp);
}