一. 实现原理
冒泡排序的相关知识,参考冒泡排序 程序员小灰
二. 具体实现
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