第一章 排序
来源:互联网 发布:南威软件 编辑:程序博客网 时间:2024/06/10 14:53
基于《啊哈!算法》的学习
桶排序
#include<iostream>#include<vector>#include<iterator>#include<algorithm>using namespace std;int main(void){ const vector<int> input_data = { 5, 3, 5, 8, 2 }; //输入数据 const int max_num = 10; //最大的整数 //输出原数据 cout << "原始:"; ostream_iterator<int> o_iter(cout, " "); copy(input_data.begin(), input_data.end(), o_iter); cout << endl; vector<int> flags(max_num + 1, 0); //标记数组(桶) for (const auto data : input_data) ++flags[data]; //进行桶计数(可以边输入边计数) cout << "排序(从小到大):"; for (int i = 0; i < flags.size(); ++i) { int flag_count = flags[i]; while (flag_count--) cout << i << ' '; } cout << endl; cout << "排序(从大到小):"; for (int i = flags.size() - 1; i >= 0; --i) { int flag_count = flags[i]; while (flag_count--) cout << i << ' '; } cout << endl; return 0;}
时间复杂度为O(M+N)
,M为桶的个数,N为待排序的个数。
桶排序1956年开始被使用,该算法的基本思想由E.J.Issac
和R.C.Singleton
提出来的。
真正的桶排序算法更加复杂。
冒泡排序
冒泡排序的基本思想:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。
如果有n个数进行排序,只需将n-1个数归位(进行n-1趟操作)。
#include<iostream>#include<vector>#include<iterator>#include<algorithm>using namespace std;int main(void){ const vector<int> input_data = { 8, 100, 50, 22, 15, 6, 1, 1000, 999, 0 }; //输出原数据 cout << "原始:"; ostream_iterator<int> o_iter(cout, " "); copy(input_data.begin(), input_data.end(), o_iter); cout << endl; vector<int> data1 = input_data; cout << "排序(从小到大):"; for (int i = 0; i < data1.size() - 1; ++i) //控制n-1次 { for (int j = 0; j < data1.size() - i - 1; ++j) //减1为了不越界(访问j+1) { if (data1[j] > data1[j + 1]) { int temp = data1[j]; data1[j] = data1[j + 1]; data1[j + 1] = temp; } } } copy(data1.begin(), data1.end(), o_iter); cout << endl; vector<int> data2 = input_data; cout << "排序(从大到小):"; for (int i = 0; i < data2.size() - 1; ++i) { for (int j = 0; j < data2.size() - i - 1; ++j) { if (data2[j] < data2[j + 1]) { int temp = data2[j]; data2[j] = data2[j + 1]; data2[j + 1] = temp; } } } copy(data2.begin(), data2.end(), o_iter); cout << endl; return 0;}
冒泡排序的核心部分是双重嵌套循环,时间复杂度为O(N^2)
。
冒泡排序1956年有人开始研究,但是复杂度太高不推荐,Donald E.Knuth(高德纳,1974年图灵奖获得者)——冒泡排序除了它迷人的名字和导致了某些有趣的理论问题这一事实之外,似乎没有什么值得推荐的。
快速排序
快速排序之所以比较快,是因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样只能在相邻的数之间进行交换,交换的距离就大得多。因此,总的比较和交换次数就少了,速度自然就提高了。
当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度是O(N^2)
,它的平均时间复杂度为O(NlogN)
。
快速排序是基于“二分”的思想。
#include<iostream>#include<vector>#include<iterator>#include<algorithm>using namespace std;void quick_sort(vector<int> & data, int left, int right){ if (left < right) //至少是两个数 { int p = data[left]; //取最左边为基准数 int i = left, j = right; while (i < j) { while (data[j] > p && i < j) --j; while (data[i] <= p && i < j) ++i; if (i < j) //i和j没有相遇,交换 { int temp = data[i]; data[i] = data[j]; data[j] = temp; } } data[left] = data[i]; data[i] = p; quick_sort(data, left, i - 1); quick_sort(data, i + 1, right); }}int main(void){ vector<int> input_data = { 6, 1, 2, 7, 9, 3, 4, 5, 10, 8 }; //输出原数据 cout << "原始:"; ostream_iterator<int> o_iter(cout, " "); copy(input_data.begin(), input_data.end(), o_iter); cout << endl; cout << "排序(从小到大):"; quick_sort(input_data, 0, input_data.size() - 1); copy(input_data.begin(), input_data.end(), o_iter); cout << endl; return 0;}
快速排序由C.A.R.Hoare(Charles Antony Richard Hoare)在1960年提出,之后又有许多人做了进一步的优化。他在ALGOL X的设计中发明了case语句,在1980年获得了图灵奖。
0 0
- 第一章 排序
- 第一章排序----桶排序
- 算法第一章:冒泡排序
- 第一章---桶排序2
- 《啊哈算法》第一章 排序
- 八大排序 第一章 【开始】
- 《编程珠玑》第一章-位图排序
- 【编程珠玑】第一章电话号码排序
- 第一章排序 算法(java)
- 啊哈!算法读书笔记 | 第一章 排序
- 算法学习第一章-----排序算法
- 编程珠玑第一章,电话号码排序问题
- 磁盘排序(编程珠玑第一章)
- 编程珠玑 第一章 大数据排序
- 学习《算法导论》第一章 插入排序 总结
- "编程珠玑" 第一章 磁盘文件排序问题
- 【C++】【啊哈!算法】第一章——排序
- 第一章 游戏之乐 一摞饼的排序
- PHP和Mysql锁机制
- C++作业7
- 【Node.js】mongoose教程07--排重与计数
- ACM:蓝桥杯:神奇算式
- Android MINA框架之实战总结(一) Mina连接,断开,重连
- 第一章 排序
- 有监督学习、无监督学习、参数估计、非参数估计
- C++第七次作业
- Codeforces 676C Vasya and String
- SQL Server 2005 对象名无效
- 统一建模语言 UML (2)
- 阅读程序
- 深度学习(三十七)优化求解系列之(1)简单理解梯度下降
- 【Node.js】mongoose教程08--更新