您现在的位置是:首页 >其他 >数据结构与算法基础(王卓)(34):交换排序之冒泡排序网站首页其他
数据结构与算法基础(王卓)(34):交换排序之冒泡排序
目录
冒泡排序:(在我们【前面排序的顺序表】的前置条件的要求之下,后面不再赘述)
另外,如果还要温习回顾一下之前我们是怎么学这个玩意的,可以看看:
前置条件:
#include<iostream>
using namespace std;
#define MAXSIZE 20 //记录最大个数
typedef int KeyType; //关键字类型
typedef int InfoType;
//定义每个记录(数据元素)的结构
struct RecType
//Record Type:每条记录的类型
{
KeyType key; //关键字
InfoType otherinfo; //其他数据项
};
struct SqList
//顺序表(的)结构
{
RecType r[MAXSIZE + 1];
//类型为【记录类型】的数组
//r[0]一般做哨兵或缓冲区
int length; //顺序表长度
};
冒泡排序:(在我们【前面排序的顺序表】的前置条件的要求之下,后面不再赘述)
第一步:
第一次/遍遍历,先确定最后的/最大的一个元素
写(第)一次冒泡排序的程序
void BubbleSort(SqList& L)
{
for (int i = 1; i <= L.length; i++)
{
if (L.r[i].key > L.r[i + 1].key)
{
L.r[0] = L.r[i + 1];
L.r[i + 1] = L.r[i];
L.r[i] = L.r[0];
}
}
}
默认数据位置从位序为1的位置开始存储,0的位置空出来,用来存储哨兵/作为暂存空间
第二步:
后面每次循环确定剩余元素最后的一个元素
剩余能进行排序比较的元素越来越少,每多比较循环排序一次:
就确定一个里面最大的元素,就少一个下一轮进入(拿来)排序比较的元素
So... / 所以:
void BubbleSort(SqList& L)
{
for (int j = L.length; j > 0; j--)
//j > 1 是不是也可以?
//反正最后都只剩下一个元素了,肯定是最小的那一个,你还比什么比
for (int i = 1; i < j; i++)
{
if (L.r[i].key > L.r[i + 1].key)
{
L.r[0] = L.r[i + 1];
L.r[i + 1] = L.r[i];
L.r[i] = L.r[0];
}
}
}
j 表示的意思就是:
我们每一次(这一次)循环一共比较多少个元素
这一次循环确定的是整个排序表里面第几个/大的元素
而 i 表示/用来指向的则是每一次拿来进行比较的前面一个元素
注意:
除了上一步我们完善闭环了多次循环的设计语句之外,这里我们还有一个改动是需要注意的:
for (int i = 1; i < j; i++)
这里,我们用的符号是“<”而不是前面使用的“<=”
这里的这个改动,可以说是我们冒泡算法排序当中的一个精髓
原因其实也很简单:
因为我们比较的对象是:L.r[i].key 和 L.r[i + 1].key
不是:L.r[i].key 和 L.r[i - 1].key
当然,实际上,并不是说这里后面第二步和前面第一步就有什么不一样的地方,实际上只是我们第一步也写错了而已,哈哈
另外,如果还要温习回顾一下之前我们是怎么学这个玩意的,可以看看:
书P85 例5-3 冒泡算法问题_i<k,诺a[i小于a[k]_宇 -Yu的博客-CSDN博客
不过我个人觉得是没什么必要,因为我感觉还是我这里写的(一遍直接写出来的)清晰明了和舒适
前面的这个文章写的有点像一团浆糊,哈哈
Anyway,关于这个冒泡排序怎么写,其实还是各花入各眼,以下收集了部分各个版本,不过我觉得只要知道,我这个是对的,那就行了:
Github版本:
for(int i=0;i<L.length;++i)
{
for(int j=0;j<L.length - i;++j)
PPT标准答案:
void BubbleSort(SqList& L)
{
int i, j, m;
RecType temp; //交换时临时储存
bool flag = 1; //标记是否有交换
for (m = 1; m < L.length - 1 && flag; m++)
{
flag = 0;
for (j = 1; j <= L.length - m; j++)
{
if (L.r[j].key > L.r[j + 1].key)
{
flag = 1;
temp = L.r[j];
L.r[j] = L.r[j + 1];
L.r[j + 1] = temp;
}
}
}
}
另外的,至于我前面自己文章里面写的其他写法我这里就不再赘述了,有兴趣的自己去看去
第三步:
补充一下PPT上面说的改进方法:
思路:
因为每次排序都是遍历都是前面所有元素组织起来的整张表,那么也就是说:
如果我们有一遍遍历的时候,前面的元素都已经有序了,不用我们去操作调换位置了
那就结束了,整张表已经全部都有序了
后面我们也不用再去重复遍历的操作了
方法:
搞个 flag 来标记前面一趟排序当中是不是前面的元素都已经有序,flag = 0就不用遍历了
实现:
将这个思想方法本土化:
void BubbleSort(SqList& L)
{
bool flag = 1;
for (int j = L.length; j > 0 && flag; j--)
for (int i = 1; i < j; i++)
{
flag = 0;
if (L.r[i].key > L.r[i + 1].key)
{
flag = 1;
L.r[0] = L.r[i + 1];
L.r[i + 1] = L.r[i];
L.r[i] = L.r[0];
}
}
}