# 通常的冒泡排序
假设按照升序排序。
排序思想:
第一趟排序:首先将第一个元素和第二个元素比较,若第一个元素大于第二个元素,交换它们,然后比较第二个元素和第三个元素,……,知道第n-1个元素和第n个元素比较, 第一趟排序将最大的元素放在了最后一位(第n位);
第二趟排序:对前n-1个元素元素执行同样操作,其结果是将第二大的元素放在了数组第n - 1的位置上。
第i趟排序:依次比较前n - i + 1个元素,将这n - i + 1个元素中最大的元素放到第n - i + 1位上。
设数组大小为n;比较相邻的两个数,如果第一个大于第二个,则交换两个数据;这样,第一个排序后,比较了n-1次,最大的数在数组末尾。然后n = n- 1,在n不为0情况下继续排序,否则排序完成。
~~~
void bubble_sort1(int a[], int size) {
int i;
for (i = 0; i < size; ++i) {
int j;
for (j = 1; j < size - i; ++j) {
if (a[j - 1] > a[j]) {
int temp = a[j - 1];
a[j - 1] = a[j];
a[j] = temp;
}
}
}
}
~~~
# 改进版本
设置一个标记flag,如果某次排序发生了交换flag为真;否则flag为假,排序结束。排序结束的标志是某趟排序没有发生交换。那么排序所需要的趟数k范围是1 <= k < n。若初始序列为有序的,则只需要一趟排序,在排序过程中进行n -1 次的关键字的比较,且不需要移动元素。若初始序列为逆序的,则需要n - 1趟排序,共需要n(n - 1) / 2次比较,并作等数量级的元素移动。
~~~
void bubble_sort2(int a[], int size) {
int k;
bool flag;
k = size;
flag = true;
while (flag) {
flag = false;
int j;
for (j = 1; j < k; j++) {
int temp;
if (a[j - 1] > a[j]) {
temp = a[j - 1];
a[j - 1] = a[j];
a[j] = temp;
flag = true;
}
}
k--;
}
}
int main() {
int a[] = {9,4,2,6,1, 1, 1};
cout << sizeof(a) / sizeof(int) << endl;
bubble_sort1(a, sizeof(a) / sizeof(int));
//bubble_sort1(a, sizeof(a) / sizeof(int));
int i;
for (i = 0; i < sizeof(a) / sizeof(int); ++i)
cout << a[i] << " ";
cout << endl;
return 0;
}
~~~
该排序算法用到了交换两个数的函数。参考[这里](http://blog.csdn.net/u013074465/article/details/44342629)查看面试题“不借助其他变量,交换两个数”。
- 前言
- Josephus约瑟夫问题及其变种
- 链表的常见实现
- 二叉树遍历、插入、删除等常见操作
- 二叉堆的插入删除等操作C++实现
- 插入排序和希尔排序
- 堆排序
- 归并排序及其空间复杂度的思考
- 快速排序的几种常见实现及其性能对比
- 红黑树操作及实现
- 整数的二进制表示中1的个数
- 位操作实现加减乘除四则运算
- 冒泡排序的改进
- 直接选择排序
- 不借助变量交换两个数
- 基础排序算法总结
- AVL树(Adelson-Velskii-Landis tree)
- avl树的C++实现
- 动态规划之钢条分割
- hash函数的基本知识
- 动态规划:求最长公共子串/最长公共子序列
- 最长递增子序列
- 称砝码问题
- 汽水瓶
- 字符串合并处理(二进制位的倒序)
- 动态规划:计算字符串相似度
- m个苹果放入n个盘子
- 生成k个小于n的互不相同的随机数
- 栈和队列的相互模拟
- 字符串的排列/组合
- KMP(Knuth-Morris-Pratt)算法
- n个骰子的点数
- 位运算的常见操作和题目