鸡尾酒排序
冒泡排序的思想:
冒泡排序的每一个元素都像气泡一样,根据自身大小,一点一点向着数组的一侧移动。
算法的每一轮从都是从左到右比较元素,进行单向的位置交换。
鸡尾酒排序做了怎样的优化呢?
鸡尾酒排序的元素比较和交换过程是双向的。
看这样一个例子:
有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;
}