算法第四版 第二章 排序算法 c++实现
最近在学习 算法(第四版)这本书,正好前段时间学了c++,就决定全用c++实现一波,也方便我 熟悉c++的特性。不得不说,c++确实是个有强大,又麻烦的语言。
初学c++,代码规范之类的可能做的不太好,还希望有大佬看到了指正一下。
几点和书上不太一样的地方
- 为了和C++标准库的风格类似,算法传入参数全部为迭代器类型(可以适配不同容器),因此实现大量使用了模板
- 算法实现过程需要迭代器支持加减法,所以需要容器支持随机访问,内置数组、vector、deque都可以适配
- 对于区间按照传统 全部取左闭右开区间,即begin为第一个元素,end为最后一个元素的后一个元素,和书上的部分地方不太一样,不过个人感觉这样确实更规范、美观。
- 尽量写 != 和 <
测试方法类
#pragma once
#include <chrono>
#include <iostream>
template<typename Iter>
bool isSorted(const Iter& begin, const Iter& end) {
for (Iter i = begin + 1 ; i != end; ++i) {
if (*i < *(i - 1)) {
return false;
}
}
return true;
}
template<typename Iter>
int SortTest(const Iter& begin, const Iter& end, void(*s)(const Iter&, const Iter&)) {
int time0 = clock();
(*s)(begin, end);
int time1 = clock();
if (isSorted(begin, end)) {
std::cout << "sort secceed spend time = " << time1 - time0 << std::endl;
return time1 - time0;
}
else {
std::cout << "sort failed" << std::endl;
return 0;
}
}
//main函数里一般这么写
using namespace std;
int main() {
const int N = 10000;
vector<unsigned int> v;
v.reserve(N);
default_random_engine e(0);
uniform_int_distribution<> u(0, 10000);
MaxPQ<int> pq;
for (int i = 0; i < N; ++i) {
v.push_back(u(e));
}
v[0] = 0; //堆排序需要这句,因为堆排序不排第一个
for (int i = 0; i < 10; ++i) {
auto temp(v);
SortTest(temp.begin(), temp.end(), HeapSort::sort);
}
cout << endl << endl;
for (int i = 0; i < 10; ++i) {
auto temp(v);
SortTest(temp.begin(), temp.end(), Quick::sort);
}
return 0;
}
初级排序算法
和书上不太一样的是,书上的测试结果是插入排序效率高于选择排序,而我这里测试时选择排序高。
原因可能是c++和java的差异造成的,毕竟java全员指针,swap的成本很低,和访问数组成本差不多, 而c++交换成本可能就高了。
选择排序
#pragma once
#include <utility> //标准库的swap函数在这里
class Selection {
template<typename Iter>
void sort(const Iter& begin, const Iter& end) {
using std::swap; //使用swap的准备,会优先使用自定义的,再使用标准库的
for (Iter i = begin; i != end; ++i) {
Iter min = i;
for (Iter j = i; j != end; ++j) {
if (*j < *min) {
min = j;
}
}
swap(*i, *min);
}
}
};
插入排序
#pragma once
#include <utility>
class Insertion {
template<typename Iter>
void sort(const Iter& begin, const Iter& end) {
using std::swap;
if (begin == end) {
return; } //空容器的排序
for (Iter i = begin + 1;