排序算法之一 冒泡排序(C++版本)

一. 实现原理

冒泡排序的相关知识,参考冒泡排序 程序员小灰

二. 具体实现

1. 初始版本
void BubbleSort_Init(int* pData, int size)
{
	if (nullptr == pData || size <= 0) return;

	for (int i = 0; i < size - 1; ++i) // 轮数为size - 1
	{
		for (int j = 0; j < size - 1 - i; ++j) // 注意j的上限为size-1-i, 确保j+1不越界
		{
			if (pData[j] > pData[j+1]) std::swap(pData[j], pData[j+1]);
		}
	}
}

每一轮结束之后,如果这轮中没有进行一次数据交换,表明数组已经有序,无需再进行操作。

2. 改进版本
void BubbleSort_Advance(int* pData, int size)
{
	if (nullptr == pData || size <= 0) return;

	for (int i = 0; i < size - 1; ++i) // 轮数为size - 1
	{
		bool hasSwap = false; // 是否有过数据交换
		for (int j = 0; j < size - 1 - i; ++j) // 注意j的上限为size-1-i, 确保j+1不越界
		{
			if (pData[j] > pData[j + 1])
			{
				std::swap(pData[j], pData[j + 1]);
				hasSwap = true;
			}
		}

		if (!hasSwap) break; // 这一轮没有一次交换,说明已经排好序,无需再比较
	}
}

如果每轮中,只有前面进行过数据交换,后面没有。可以以最后交换过数据的位置作为下一次进行检查的终点。

3. 最终版本
void BubbleSort_Final(int* pData, int size)
{
	if (nullptr == pData || size <= 0) return;

	int endIdx = size - 1; // 每次比较的结束位置,从这个位置(包括)之后已经有序
	int lastSwapIdx = 0; // 每轮中最后交换的位置

	for (int i = 0; i < size - 1; ++i) // 轮数为size - 1
	{
		bool hasSwap = false;
		for (int j = 0; j < endIdx; ++j) // 注意j的上限为size-1-i, 确保j+1不越界
		{
			if (pData[j] > pData[j + 1])
			{
				std::swap(pData[j], pData[j + 1]);
				hasSwap = true; 
				lastSwapIdx = j;  // 更新需要比较的最终位置
			}
		}

		// 这一轮没有一次交换,说明已经排好序,无需再比较
		if (!hasSwap) break;
		endIdx = lastSwapIdx;
	}
}

三. 输出验证

加上相关的输出信息后再进行调用。

辅助函数:

void Print(int* pData, int size)
{
	for (int idx = 0; idx < size; ++idx) std::cout << pData[idx] << " ";
	std::cout << std::endl;
}

初始数据为:

int datas[10] = { 1, 2, 3, 2, 1, 6 };
1. 初始版本
void BubbleSort_Init_Output(int* pData, int size)
{
	if (nullptr == pData || size <= 0) return;

	for (int i = 0; i < size - 1; ++i) // 轮数为size - 1
	{
		std::cout << std::endl << "ROUND " << i << std::endl << std::endl;
		for (int j = 0; j < size - 1 - i; ++j) // 注意j的上限为size-1-i, 确保j+1不越界
		{
			if (pData[j] > pData[j+1])
				std::swap(pData[j], pData[j+1]);

			std::cout << "STEP " << j << ":" << std::endl;
			Print(pData, size);
		}
	}
}

调用输出

ROUND 0

STEP 0:
1 2 3 2 1 6
STEP 1:
1 2 3 2 1 6
STEP 2:
1 2 2 3 1 6
STEP 3:
1 2 2 1 3 6
STEP 4:
1 2 2 1 3 6

ROUND 1

STEP 0:
1 2 2 1 3 6
STEP 1:
1 2 2 1 3 6
STEP 2:
1 2 1 2 3 6
STEP 3:
1 2 1 2 3 6

ROUND 2

STEP 0:
1 2 1 2 3 6
STEP 1:
1 1 2 2 3 6
STEP 2:
1 1 2 2 3 6

ROUND 3

STEP 0:
1 1 2 2 3 6
STEP 1:
1 1 2 2 3 6

ROUND 4

STEP 0:
1 1 2 2 3 6
2. 改进版本
void BubbleSort_Advance_Output(int* pData, int size)
{
	if (nullptr == pData || size <= 0) return;

	for (int i = 0; i < size - 1; ++i) // 轮数为size - 1
	{
		bool hasSwap = false;

		std::cout << std::endl << "ROUND " << i << std::endl << std::endl;
		for (int j = 0; j < size - 1 - i; ++j) // 注意j的上限为size-1-i, 确保j+1不越界
		{
			if (pData[j] > pData[j + 1])
			{
				std::swap(pData[j], pData[j + 1]);
				hasSwap = true;
			}

			std::cout << "STEP " << j << ":" << std::endl;
			Print(pData, size);
		}

		// 这一轮没有一次交换,说明已经排好序,无需再比较
		if (!hasSwap) break;
	}
}

调用输出

ROUND 0

STEP 0:
1 2 3 2 1 6
STEP 1:
1 2 3 2 1 6
STEP 2:
1 2 2 3 1 6
STEP 3:
1 2 2 1 3 6
STEP 4:
1 2 2 1 3 6

ROUND 1

STEP 0:
1 2 2 1 3 6
STEP 1:
1 2 2 1 3 6
STEP 2:
1 2 1 2 3 6
STEP 3:
1 2 1 2 3 6

ROUND 2

STEP 0:
1 2 1 2 3 6
STEP 1:
1 1 2 2 3 6
STEP 2:
1 1 2 2 3 6

ROUND 3

STEP 0:
1 1 2 2 3 6
STEP 1:
1 1 2 2 3 6
3. 最终版本
void BubbleSort_Final_Output(int* pData, int size)
{
	if (nullptr == pData || size <= 0) return;

	int endIdx = size - 1; // 每次比较的结束位置,从这个位置(包括)之后已经有序
	int lastSwapIdx = 0; // 每轮中最后交换的位置

	for (int i = 0; i < size - 1; ++i) // 轮数为size - 1
	{
		bool hasSwap = false;
		std::cout << std::endl << "ROUND " << i << std::endl << std::endl;
		for (int j = 0; j < endIdx; ++j) // 注意j的上限为size-1-i, 确保j+1不越界
		{
			if (pData[j] > pData[j + 1])
			{
				std::swap(pData[j], pData[j + 1]);
				hasSwap = true;       
				lastSwapIdx = j;  // 更新需要比较的最终位置
			}

			std::cout << "STEP " << j << ":" << std::endl;
			Print(pData, size);
		}

		// 这一轮没有一次交换,说明已经排好序,无需  再比较
		if (!hasSwap) break;
		endIdx = lastSwapIdx;
	}
}

调用输出


ROUND 0

STEP 0:
1 2 3 2 1 6
STEP 1:
1 2 3 2 1 6
STEP 2:
1 2 2 3 1 6
STEP 3:
1 2 2 1 3 6
STEP 4:
1 2 2 1 3 6

ROUND 1

STEP 0:
1 2 2 1 3 6
STEP 1:
1 2 2 1 3 6
STEP 2:
1 2 1 2 3 6

ROUND 2

STEP 0:
1 2 1 2 3 6
STEP 1:
1 1 2 2 3 6

ROUND 3

STEP 0:
1 1 2 2 3 6
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值