基础C++算法——冒泡排序

本文详细介绍了C++实现的基础冒泡排序、优化冒泡排序以及鸡尾酒排序算法。通过示例代码展示了每种排序算法的工作原理,包括如何减少不必要的比较和交换,提高排序效率。此外,还分析了各排序算法的时间复杂度和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值