一. 目的
1)交换排序就是,调整序列中不符合顺序的元素进行交换,最终序列整体符合目标次序。
2)进行冒牌排序练习。
3)算法证明:
初始:将第二个元素与第一个元素进行调整,使之符合从小到大数序。
递归步骤:将第K个元素与前K-1个元素从小到大依次调整,将不符合的元素放在K位置,K放在正确位置。此时K与正确位置元素之后的元素一一交换,K充当中间变量,直到K-1元素与K元素调整。这样得到K个元素的有序序列。
终止:i=N,整个序列顺序得到调整。算法证明完毕。
二. 代码
1)标准冒泡排序
void BubbleSort(T testArray[], int nSize){
LogInfo<T> log = LogInfo<T>();
log.ShowState("原始数组为:");
log.ShowArray(testArray,nSize);
T key(0);//中间变量
int move(0), compare(0),times(0);//移动比较记录
for (int i = 1; i < nSize; i++){
times++;
for (int j = 0; j < i; j++){
compare++;
if (testArray[i] < testArray[j]){
key = testArray[i];
testArray[i] = testArray[j];
testArray[j] = key;
move += 3;
}
}
log.ShowState("第", times, "趟数组为:");
log.ShowArray(testArray, nSize);
}
log.ShowState("最终数组为:");
log.ShowArray(testArray, nSize);
log.ShowState("移动次数:", move);
log.ShowState(" 比较次数:", compare);
log.ShowLine();
}
2)标记最大下标的移动元素法:
void BubbleSortVerExchange(T testArray[], int nSize){
LogInfo<T> log = LogInfo<T>();
T key(0);
int i(0),move(0), compare(0), times(0), nExchange(nSize - 1),nUboud(0);
log.ShowState("原始数组:");
log.ShowArray(testArray, nSize);
while (nExchange){
nUboud = nExchange;
times++;
nExchange = 0;
for (i = 0; i < nUboud; i++){
compare++;
if (testArray[i] > testArray[i + 1]){
nExchange = i;
key = testArray[i + 1];
testArray[i + 1] = testArray[i];
testArray[i] = key;
move += 3;
}
}
log.ShowState("第", times, "趟数组为:");
log.ShowArray(testArray, nSize);
}
log.ShowState("最终数组为:");
log.ShowArray(testArray, nSize);
log.ShowState("移动次数:", move);
log.ShowState(" 比较次数:", compare);
log.ShowLine();
}
3)双向,并增加最大与最小移动元素小标标记法。
void BubbleSortVerTowDirection(T testArray[], int nSize){
LogInfo<T> log = LogInfo<T>();
T key(0);
int Lbound(0), Ubound(nSize - 1),times(0),move(0),compare(0),i(0),nPos(1);
log.ShowState("原始数组为:");
log.ShowArray(testArray, nSize);
while (Lbound < Ubound && nPos){
times++;
nPos = 0;
//获取一个最大值
for (i = Lbound; i< Ubound; i++){
compare++;
if (testArray[i]>testArray[i + 1]){
key = testArray[i + 1];
testArray[i + 1] = testArray[i];
testArray[i] = key;
move += 3;
nPos = i;
}
}
if (nPos){
Ubound = nPos;
times++;
nPos = 0;
//获取一个最小值
for (i = Ubound; i > Lbound; i--){
compare++;
if (testArray[i] < testArray[i - 1]){
key = testArray[i];
testArray[i] = testArray[i - 1];
testArray[i - 1] = key;
move += 3;
nPos = i;
}
}
Lbound = nPos;
}
log.ShowState("第", times, "趟数组为:");
log.ShowArray(testArray, nSize);
}
log.ShowState("最终数组为:");
log.ShowArray(testArray, nSize);
log.ShowState("移动次数:", move);
log.ShowState(" 比较次数", compare);
log.ShowLine();
}
输出结果截图:
三.错误分析
1、冒泡排序与简单选择排序都有最值的获取特征,从这点上将二者混淆。
2、用VS编辑器,很多括号都是自动匹配的,有时不小心删掉,导致有时程序编写后存在语法错误。
3、循环体中的三个循环节,不小心书写了逗号,导致了重复定义循环变量的错误。
四. 总结
1、冒泡排序:每次新增一个待排序元素放在合适位置,然后通过两两交换实现元素的后移。
插入排序:每次新增一个待排元素,寻找到合适位置,通过哨兵变量记录待排元素,插入位置之后的元素一一后移,然后插入。与冒泡的区别就是怎么将元素放在合适位置。
选择排序:就是每次从未排序的序列中选择一个最值放在该放的位置。
2、尽管vs很智能,可能会导致自己在非智能编辑器上会产生不良习惯,但是知识经验优先,从易到难吧,等待半年后,再换用VIm编辑器。
3、尽管可以通过交换元素标记来避免不必要的循环,但是对于逆序序列,算法的并没有减少循环。改进的措施,只是提高了排序的最优处理,最坏还是没法避免。
4、算法稳定,时间复杂度O(n^2),空间复杂度O(1).
五. 后续处理
练习快速排序。
六. 参考文章
1、 八大排序算法 http://blog.youkuaiyun.com/abcbig/article/details/42774333
2、排序算法总结
http://blog.youkuaiyun.com/xuguangsoft/article/details/7953100
本文详细介绍了冒泡排序的原理及三种不同的实现方式,包括标准冒泡排序、标记最大下标的移动元素法和双向并增加最大与最小移动元素标示法,并分析了其优缺点。
3605

被折叠的 条评论
为什么被折叠?



