冒泡排序 及其两次优化
2016-06-12 22:41
453 查看
冒泡排序 及其两次优化
第二次:第2大的“上浮”到最上面
加入标记,当发现数组已排序时,即内层循环没有发生交换时,证明数组已经有序,程序结束。
因为内层循环长度的设定依据是:经过i排序后,数组的后i-1个元素是已排序好的;
但实际上i次排序的循环长度取决于i-1次排序时最后的交换位置。
例如:第i-1次排序后,最后交换位置是index,则表明index之后的元素都已经排好序。
1 冒泡排序:原版
第一次,最大的“上浮”到最上面第二次:第2大的“上浮”到最上面
void bubble_sort(int *a, int n){ for(int i = 0; i < n - 1; ++i){ // 每趟排序,最大值“沉底”,所以共需n-1趟, for(int j = 0; j < n - i - 1; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底” if(a[j] > a[j+1]) swap(a[j], a[j+1]); } } }
2 第一次优化
当数组是已排序的,原版冒泡排序仍要遍历n2/2n^2/2次。加入标记,当发现数组已排序时,即内层循环没有发生交换时,证明数组已经有序,程序结束。
void bubble_sort2(int *a, int n){ bool exchange = false; for(int i = 0; i < n - 1; ++i){ // 每趟排序,最小值“沉底”,所以共需n-1趟, for(int j = 0; j < n - i - 1; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底” if(a[j] > a[j+1]) { swap(a[j], a[j+1]); exchange = true; } } if(!exchange) break; } }
3 第二次优化
如果只有0,1元素,那么按照第一次优化的算法,仍然要遍历2∗n2*n次。因为内层循环长度的设定依据是:经过i排序后,数组的后i-1个元素是已排序好的;
但实际上i次排序的循环长度取决于i-1次排序时最后的交换位置。
例如:第i-1次排序后,最后交换位置是index,则表明index之后的元素都已经排好序。
#include <iostream> #include <algorithm> #include <cstdlib> using namespace std; void print_array(int *a, int from, int to){ for(int i = from; i <= to; ++i){ cout << a[i] <<" "; } cout << endl; } void bubble_sort3(int *a, int n){ bool exchange = false; int index = 0; // 最后交换的位置 int mark = n - 1; // 标记内部循环的范围 for(int i = 0; i < n - 1; ++i){ // 每趟排序,最小值“沉底”,所以共需n-1趟, for(int j = 0; j < mark; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底” if(a[j] > a[j+1]) { swap(a[j], a[j+1]); exchange = true; index = j; } } if(!exchange) break; mark = index; } } int main() { int n = 1000; int K = 10; int *a = new int ; for(int i = 0; i < n; ++i){ a[i] = rand() % n; } bubble_sort3(a, n); print_array(a, 0, K-1); return 0; }
附:测试程序
#include <iostream> #include <algorithm> #include <cstdlib> using namespace std; void print_array(int *a, int from, int to){ for(int i = from; i <= to; ++i){ cout << a[i] <<" "; } cout << endl; } void bubble_sort3(int *a, int n){ bool exchange = false; int index = 0; // 最后交换的位置 int mark = n - 1; // 标记内部循环的范围 for(int i = 0; i < n - 1; ++i){ // 每趟排序,最小值“沉底”,所以共需n-1趟, for(int j = 0; j < mark; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底” if(a[j] > a[j+1]) { swap(a[j], a[j+1]); exchange = true; index = j; } } if(!exchange) break; mark = index; } } int main() { int n = 1000; int K = 10; int *a = new int ; for(int i = 0; i < n; ++i){ a[i] = rand() % n; } bubble_sort3(a, n); print_array(a, 0, K-1); return 0; }
相关文章推荐
- 第 5 章 内置函数
- Oracle学习 第4天之高级查询
- win10安装MySQL
- linux配置hosts
- jsp 与 html 区别
- Activity的启动模式
- oracle复习 - day01
- onInterceptTouchEvent、onTouchEvent、onTouch
- python
- oracle相关的下载地址
- ServiceConnection中onServiceConnected不执行
- 【BZOJ1069】[SCOI2007]最大土地面积【凸包】
- AS中jar包和aar包的导出与导入
- 阴历与阳历
- ListView 悬停 + 如何在每个Adapter获取没个View
- 如何解决访问Oracle时报错:“The Network Adapter could not establish the connection”?
- AR(增强现实) unity+vuforia 基础教程(2)!
- js 数组排序和算法排序
- HDU 2715 Herd Sums
- android微信支付