重点:插入排序、选择排序、冒泡、快速排序。 要求:
被排序的对象由计算机随机生成。算法中增加比较次数和移动次数的统计功能。main.h #include"sort.h" void main() {
vector<Etype> sqlist; random_device rd; //随机种子生成器 seed_seq sd = { rd(), rd(), rd() };//种子序列 default_random_engine rng{ sd };//随机数生成器 CreateRandomSqlist(20, sqlist,rng);//创建内容随机的表 PrintKey(sqlist);//打印表 Count Count1= InsertSort<vector<Etype>, Count>(sqlist);//插入排序 cout << "插入排序:比较次数" << Count1.compare << " " <<"移动次数"<< Count1.motion<<'\n'; PrintKey(sqlist); shuffle(sqlist.begin(), sqlist.end(), rng);//打乱原表 PrintKey(sqlist); Count Count2 = SlectSort< vector<Etype>, Count>(sqlist); cout << "选择排序:比较次数" << Count2.compare << " " << "移动次数" << Count2.motion << '\n'; PrintKey(sqlist); shuffle(sqlist.begin(), sqlist.end(), rng);//打乱原表 PrintKey(sqlist); Count Count3 = BubbleSort<vector<Etype>, Count>(sqlist);//冒泡排序 cout << "冒泡排序:比较次数" << Count3.compare << " " << "移动次数" << Count3.motion << '\n'; PrintKey(sqlist); shuffle(sqlist.begin(), sqlist.end(), rng);//打乱原表 PrintKey(sqlist); Count Count4 = QuickSort(sqlist); cout << "快速排序:比较次数" << Count4.compare << " " << "移动次数" << Count4.motion << '\n'; PrintKey(sqlist); system ("pause");}
sort.h
#pragma once #include <vector #include <iterator #include <iostream #include <random #include<algorithm using namespace std;
//顺序表储存数据类型 struct Etype { int key; string name; }; //统计 比较和移动 次数 struct Count { size_t compare; size_t motion; };
void CreateRandomSqlist(size_t length, vector& sqlist, default_random_engine rng); void PrintKey(vector sqlist); template <typename T, typename Tr> Tr InsertSort(T& L);//直接插入排序 template <typename T, typename Tr> Tr SlectSort(T& L);//简单选择排序 template <typename T, typename Tr>Tr BubbleSort(T& L);//冒泡排序
//创建指定长度,vector顺序表,数据key随机 void CreateRandomSqlist(size_t length, vector &sqlist, default_random_engine rng) {
uniform_int_distribution<> dist(0, 200);//随机数均匀分布范围 Etype q; for (size_t i = 0; i <= length; i++)//第0个作插入排序时暂存器,实际创建 length+1个节点 { sqlist.emplace_back( q = { dist(rng) });//随机数节点压入表 }}
//打印顺序表key值 void PrintKey(vector sqlist) { for(vector::iterator iter = sqlist.begin()+1; iter != sqlist.end(); ++iter)//第0个作排序时暂存器,不打印 { cout << (*iter).key << " ";// *解除迭代器 & 引用 } cout << ‘\n’; //可以使用范围 for 循环更加简单地完成相同操作 //for (auto num : sqlist) 相当于 auto && __range = (sqlist); for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin) //{ // // no deference operator // cout << num.key << " "; //} }
//直接插入排序 template <typename T, typename Tr> Tr InsertSort(T& L) {
int i, j; Tr count1 = { 0,0 }; for (i = 2; i < L.size(); ++i) { count1.compare++; if (L[i].key < L.data()[i - 1].key)//i比前一个小 需插入有序子表 { L[0] = L[i];//将待插入的记录暂存到监视哨 L[i] = L[i - 1];//L[i - 1]后移 count1.motion = count1.motion + 2; for (j = i - 2; L[0].key < L[j].key; --j)//从i的前一个的前一个开始向前寻找插入点 { count1.compare++; L[j + 1] = L[j];//逐个后移 count1.motion++; }; count1.compare++;//插入点循环内最后一次比较 L[j + 1] = L[0];//插入 count1.motion++; } } return count1;}
//简单选择排序 template <typename T, typename Tr> Tr SlectSort(T& L) { size_t i,j,small; size_t l = L.size(); Tr count1 = { 0,0 }; for ( i = 1; i < l; i++) { small = i; for (j = i+1; j< l; j++ ) { count1.compare++; if (L[j].key<L[small].key) { small = j; } } if (small!=i) {//交换 L[0] = L[i]; L[i] = L[small]; L[small] = L[0]; count1.motion = count1.motion +3; } } return count1; }
//冒泡排序 template <typename T, typename Tr> Tr BubbleSort(T& L) { bool flag = 1; size_t l = L.size(); size_t i, j; Tr count1 = { 0,0 }; for (i = 1; ((i < l-1)&&flag); i++) { flag = 0; for (j = 1; j <l-i; j++) { count1.compare++; if (L[j].key > L[j+1].key) { flag = 1; L[0] = L[j]; L[j] = L[j + 1]; L[j + 1] = L[0];//交换 count1.motion = count1.motion + 3; } } } return count1; }
//快速排序
auto Partition(vector& sqlist, size_t low, size_t high, Count &CountQ) {
sqlist[0] = sqlist[low]; auto pivotkey = sqlist[low].key; while (low < high) { while ((low < high) && (sqlist[high].key >= pivotkey)) { CountQ.compare++; --high; } sqlist[low] = sqlist[high]; while ((low < high) && (sqlist[low].key <= pivotkey)) { CountQ.compare++; ++low; } sqlist[high] = sqlist[low]; CountQ.motion = CountQ.motion + 2; } sqlist[low] = sqlist[0]; return low;}
void QSort(vector& sqlist, size_t low, size_t high, Count& CountQ) { if (low < high) { auto pivotloc = Partition(sqlist, low, high, CountQ); QSort(sqlist, low, pivotloc-1, CountQ); QSort(sqlist, pivotloc+1, high, CountQ); } }
auto QuickSort(vector& sqlist) { Count CountQ = { 0,0 }; QSort(sqlist, 1, sqlist.size() - 1, CountQ); return CountQ; }