数据结构与算法基础(王卓)(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];
            }
        }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值