// C++冒泡排序算法(参考《漫画算法》)
#include <iostream>
using namespace std;
int main (void)
{
// int even_nums[10] = {21, 85, 7, 22, 65, 42, 31, 2, 67, 8};
// int enen_nums_len = 10;
// int odd_nums[11] = {21, 85, 7, 22, 65, 42, 31, 2, 67, 8, 82};
// int odd_nums_len = 11;
int input_nums[10] = {21, 85, 7, 22, 65, 42, 31, 2, 67, 8};
int nums[10];
int nums_len = 10;
// ===================== 基础冒泡排序 =====================
memcpy(nums, input_nums, sizeof(nums));
for(int i=0; i<nums_len-1; ++i) // 外循环遍历所有元素(第一个不用,因为排序后其他肯定都比它大)
{
for(int j=0; j<nums_len-i-1; ++j) // 内循环遍历上循环未定序元素
{
if(nums[j] > nums[j+1])
{
// 交换
int tmp_num = nums[j];
nums[j] = nums[j+1];
nums[j+1] = tmp_num;
}else{;}
}
}
cout << endl << endl << "基础冒泡排序:" << endl;
cout << "排序后数组:" << endl;
for(int k=0; k<nums_len; ++k)
{
cout << nums[k] << ' ';
}
cout << endl;
cout << "该算法为稳定排序" << endl;
cout << "时间复杂度为:O(n^2)" << endl;
cout << "空间复杂度为:O(1)" << endl;
// ===================== 优化冒泡排序 =====================
// 在原先的基础上增加了无序区的边界,有序的数组就不重复排序了
memcpy(nums, input_nums, sizeof(nums));
int sort_border = nums_len-1; // 无序边界
int lst_chg_index = 0; // 最后一次交换索引
bool is_sorted = true;
for(int i=0; i<nums_len-1; ++i) // 外循环遍历所有元素(第一个不用,因为排序后其他肯定都比它大)
{
is_sorted = true;
for(int j=0; j<sort_border; ++j) // 内循环遍历未定序元素
{
if(nums[j] > nums[j+1])
{
// 交换
int tmp_num = nums[j];
nums[j] = nums[j+1];
nums[j+1] = tmp_num;
is_sorted = false; // 表示还未完成排序
lst_chg_index = j; // 最后一次交换元素的索引
}else{;}
}
sort_border = lst_chg_index; // 设置下个内循环的边界,用于提前结束内循环
if (is_sorted) {break;} // 全部有序后跳出,用于终止外循环
}
cout << endl << endl << "优化冒泡排序:" << endl;
cout << "排序后数组:" << endl;
for(int k=0; k<nums_len; ++k)
{
cout << nums[k] << ' ';
}
cout << endl;
cout << "该算法为不稳定排序,优于普通的冒泡排序" << endl;
// ===================== 鸡尾酒排序 =====================
// 双向排序,解决{2 3 4 5 6 7 1 8}中间已经有序却还要全部重排的问题
memcpy(nums, input_nums, sizeof(nums));
bool is_sorted2 = true;
for(int i=0; i<nums_len/2; ++i) // 外循环遍历所有元素(第一个不用,因为排序后其他肯定都比它大)
{
is_sorted2 = true;
// 奇数轮,从左向右
for(int j=i; j<nums_len-i-1; ++j) // 内循环遍历未定序元素
{
if(nums[j] > nums[j+1])
{
// 交换
int tmp_num = nums[j];
nums[j] = nums[j+1];
nums[j+1] = tmp_num;
is_sorted2 = false; // 表示还未完成排序
}else{;}
}
if (is_sorted2) {break;} // 全部有序后跳出,用于终止外循环
is_sorted2 = true;
// 偶数轮,从右向左
for(int j=nums_len-i-1; j>i; --j) // 内循环遍历未定序元素
{
if(nums[j] < nums[j-1])
{
// 交换
int tmp_num = nums[j];
nums[j] = nums[j-1];
nums[j-1] = tmp_num;
is_sorted2 = false; // 表示还未完成排序
}else{;}
}
if (is_sorted2) {break;} // 全部有序后跳出,用于终止外循环
}
cout << endl << endl << "鸡尾酒排序:" << endl;
cout << "排序后数组:" << endl;
for(int k=0; k<nums_len; ++k)
{
cout << nums[k] << ' ';
}
cout << endl;
cout << "该算法在特定情况下减少排序回合数,但是代码量翻倍" << endl;
getchar();
return 0;
}
基础C++算法——冒泡排序
最新推荐文章于 2025-04-13 21:28:39 发布