冒泡排序的思想:
冒泡排序的每一个元素都像气泡一样,根据自身大小,一点一点向着数组的一侧移动。 算法的每一轮从都是从左到右比较元素,进行单向的位置交换。
鸡尾酒排序做了怎样的优化呢?鸡尾酒排序的元素比较和交换过程是双向的。
看这样一个例子:
有8个数 组成一个无序数列:2,3,4,5,6,7,8,1,从小到大排序。
按照冒泡排序的思想,过程如下:
鸡尾酒排序过程:
第一轮
第一个循环从左向右比较并交换元素( 1和7交换)
第二个循环从右向左比较并交换元素
接下来1和6比较,元素1小于6,所以1和6交换位置:
接下来1和5比较,元素1小于5,所以1和5交换位置:
接下来1和4交换,1和3交换,1和2交换,最终成为了下面的结果:
第二轮
需要重新从左向右比较和交换:
1和2比较,位置不变;2和3比较,位置不变;3和4比较,位置不变......6和7比较,位置不变。
没有元素位置交换,证明已经有序,排序结束。
代码整体思路:
代码外层的大循环控制着所有排序回合,
大循环内包含两个小循环,第一个循环从左向右比较并交换元素,第二个循环从右向左比较并交换元素。
#include<iostream> using namespace std; void show(int* arr, int len) { for (int i = 0; i<len; i++) { cout << arr[i]<<" "; } cout << endl; } void sort(int* arr, int len) { for (int i = 0; i < len/2; i++) { bool isSorted= true; //标记 //奇数轮,从左向右比较交换,将最大值排到队尾 for (int j = i; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; isSorted = false;//有元素交换,所以不是有序,标记为 false } } if (isSorted) { break; } isSorted = true; //偶数轮,从右向左比较交换,将最小值排到队头 for (int j = len - (i + 1) - 1; j > i; j--) { if (arr[j] < arr[j - 1]) { int tmp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = tmp; isSorted = false;//有元素交换,所以不是有序,标记为 false } } if (isSorted) { break; } } } int main() { int arr[]= {3,4,5,6,7,8,9,2}; int len = sizeof(arr) / sizeof(arr[0]); show(arr, len); sort(arr,len); show(arr, len); return 0; }