資料結構與演算法總結——常見排序演算法(未完待續)
阿新 • • 發佈:2018-11-23
- 本文包含的排序演算法
- 氣泡排序
- 插入排序
- 選擇排序
- 歸併排序
- 快速排序
- 希爾排序
- 堆排序
- 桶排序
- 基數排序
- 本文關於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);
}