冒泡排序
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 1,3,5,7,9,2,4,6,8 };
int cnt = sizeof(arr) / sizeof(int);
bool swapped=true;
while (swapped)
{
swapped = false;
for (int i = 0; i < cnt; ++i)
{
for (int j = 0; j < cnt - 1 - i; ++j)
{
if (arr[j] > arr[j + 1]) // 从小排到大
{
swap(arr[j], arr[j + 1]);
swapped = true;
}
}
}
if (!swapped)
{
break;
}
}
for (int i = 0; i < cnt; ++i)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
鸡尾酒排序
#include <iostream>
using namespace std;
int main() {
int arr[] = {5, 1, 4, 2, 8, 0, 2};
bool swapped = true;
int start = 0;
int cnt = sizeof(arr) / sizeof(int);
int end = cnt - 1;
while (swapped) {
swapped = false;
for (int i = start; i < end; ++i) {
if (arr[i] > arr[i + 1]) {
swap(arr[i], arr[i + 1]);
swapped = true;
}
}
if (!swapped) {
break;
}
swapped = false;
--end;
for (int i = end - 1; i >= start; --i) {
if (arr[i] > arr[i + 1]) {
std::swap(arr[i], arr[i + 1]);
swapped = true;
}
}
++start;
}
for (int i = 0; i < cnt; ++i)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
两种排序都是基于交换相邻元素位置的排序算法,不同之处在于冒泡算法每轮只从一端开始向另一端移动,而鸡尾酒算法则来回地在序列的两端移动。这使得鸡尾酒算法可以解决某些情况下冒泡算法的效率问题,例如当存在大量逆序对时,鸡尾酒算法的效率会更高。
当存在大量逆序对时,鸡尾酒排序算法的效率会更高,原因如下:
-
双向排序:鸡尾酒排序算法在每一轮排序中同时从左到右和从右到左进行排序。当存在大量逆序对时,即数组中相邻元素的顺序与最终排序后的顺序相反,双向排序能够更快地将较大或较小的元素移动到正确的位置。
-
减少逆序对数量:由于双向排序,鸡尾酒排序算法可以更快地减少逆序对的数量。在每一轮中,至少有一个逆序对会被消除,这有助于加快整体排序的过程。
-
优化冒泡排序:鸡尾酒排序算法是冒泡排序的一种变体,而冒泡排序对逆序对的处理效果较好。通过双向排序,鸡尾酒排序算法在一定程度上优化了传统冒泡排序的性能,特别是在存在大量逆序对的情况下。
综上所述,当存在大量逆序对时,鸡尾酒排序算法的双向排序能够更有效地减少逆序对的数量,从而提高排序效率。