粉丝22.5万获赞599.8万

冒泡排序是最简单最基础的排序算法,通过解决排序的问题,可以快速体验一下算法设计的灵魂所在。假如有一组数据里面有五个数字,将这组数据进行从大到小的排列,应该怎么做呢? 依次选择两个连接的元素进行对比,将最小的移动到左边,第一对七和三,三比七小,将三移动到七的左边, 第二对七和九,七比九小不需要移动。第三对八和九,自然是将八移动到九的左边,以此类推。第四对九和一,需要将一移动到九的左边。上数的步骤进行了一次相邻数字之间的对比,数字有原来的七到一的组合, 进行了三到九这样一个新的组合。在这个过程中,我们可以看到相对比较大的数字都进行了向左的移动,最大的数字九甚至移动到了最右边,这个过程和水中泡泡上升的方式很相似,所以这也是这种 排序叫做冒泡排序的原因。上述过程中的速度对比,从左边开始到最右边为止,记做一次运算,重复上述的步骤,进行第二次运算,我们可以得到这样一个结果,以此类推。第三次, 第四次。到这一步我们可以看到,此时数字组合已经完成了从小到大的排序,无需再进行移动我们的排序任务至此完成这个完整的过程。 冒泡排序的过程我们可以看到,完成这个排序做了四次循环,每次循环中进行了四次数字之间的对比,这样就一共进行了十六次的对比。有没有更偷懒的办法,使得对比的次数变得更少,也就是速度更快的完成排序呢。好了,这期视频就到这里,我们下期视频继续解答。

哈喽,大家好,今天我们来讲冒泡排序。冒泡排序是什么?我给你抽象的演示一下,拿出我们的图画,比如说有这么三个数字,就是四、九、七这三个数字, 先让四和九他比较一下九大,所以说就放前面,四小就放后面。再让九和七比较一下九大,所以就放前面,七小就放后面。 然后经过第一轮比较,就可以把最大的给筛选出来,这是最大的对不对?九是最大的,完了之后再让他俩进行一次比较, 九是最大的,完了之后七是第二大的,所以说他在前面,四是第最小的,所以他要放在最后。同理让我们来看有四个数的先建一个,比如说七五三一, 七和五比较一下七大就放前面,再让七和三比较一下七大就放前面,让七和一比较一下七大,所以就放前面。 第一轮排序下来最大的找到了圈起来,然后再进行排序,五和一比较,呃,三,五和三比较一下 五大,所以就放前面,五和一比较一下五大,所以就放前面一放后面三,第二大的找出来了,对不对? 然后第一大的是七,然后最后再让他俩比较一下三大,放前面一放这里五七,对不对?这样就把这个一个乱序的数字排成一个有序的数字, 用程序来演示一下。找一下我们题目,建立一个数组叫 a, 它有六个数字,有这个五,这个二,这个一, 这个五,这个六,对吧?先写一个循环啊,先写一个循环,我们先找出最大值, 这缺了一个数字,有个九,这里让它循环六减一遍。现在我们就可以开始比较 f a i 大 于 a i 加一,那么就像我们刚才提到这样,让它互换一下, 用一个中间的变量来交换这两个数字,换下来完了之后就会找到这个最大的值,我们输出一下, 这里可以选一个循环的运行一下,这边起个名字冒泡,你看最大的数九他是不是出来了?好,我们继续找第二大的,第二大的是不是要把这个第一大的给排除掉,对不对? 那所以这里我们就是不是可以把它写成减二,对不对?我们来试一下减一,我这里再放个循环减二, 你看第二大的他是不是就出来了?以此类推,我们继续让他减三、减四、减五,能不能减六?不能,因为 i 等于零,如果 i 小 于零, 零小于零,零不小于零,所以他连循环都进不去都,我们都不用写,你看这样他是不是就能排出来?但是你就排个序,你用四十多行程序肯定不行啊,效率低下, 所以我们就用嵌套循环。两个循环写好之后,我们刚才是不是一直减一、减二、减三、减四、减五,这么给减下去的,对不对? 然后我们就用这个 g 来代替这个减几的这个数,这个 g 它是不是得到五,它最大,它得到五,所以说得小于等于五, 来试一下,这样就输出来了。但是啊,我们这个其实它多循环了一遍,因为啊,你们看我刚才是不是从减一开始的?我这是个零,这里改成一,这样效率就会高一点。

冒泡排序是一种简单直观的交换排序算法,核心思想是通过相邻元素两两比较交换,让较大的元素像气泡一样逐步浮到数组末尾,最终实现整体有序。

如何对这八个数字进行一个排序,同时要求这个排序的顺序是从小到大的,那接下来呢,我就来给大家分享一下冒泡排序。为了把它讲清楚,那么接下来我将用两个动画来演示一下它到底是怎么排序的。 好,那首先呢,我们看到这八个数值,那我们呢,从最整体的这种啊角度去看,我们肯定是要依次找到最大值,比如说第一次我应该在八个数值当中 啊去查找,那么呢,我去得到八个数当中的最大值,也就是九十九,然后我把它放在最后的位置,然后呢,我在剩下的七个数当中去找最大值啊,也就是八十,哎,把它放在倒数第二的位置,依次我在五个数当中去查找, 找到最大的值五十六,哎,把它放在第三大的位置,倒数第三的位置,剩下的呢,在五个值当中去找啊,找到最大值,依次排放,然后在四个数值当中去找最大值啊,二十五,在三个数当中找最大值,就是十次, 在两个数当中找最大值,哎,是十二,好,那这个时候呢,其实就已经是从小到大的排序了啊,啊,所以十一呢,我就不用管他了,那在这呢,也就是说我有八个数值要排序,我进行了七轮去排序啊,七轮查找啊, 八个数用七轮查找啊,查找到七个这个值,然后剩下一个值当然就是最小值了啊,是这么一个顺序啊,好,这是这么一个最整体轮廓的思路。然后那每一轮我们如何去查找呢?哎,你怎么在这范围之内找到这个最大值呢?好, 我们看第二个动画,第二个动画呢,和刚才一样,只不过是我把每一轮找最大值的这个操作更加的具体进行说明啊。好,那假设说现在我们是第一轮,我们要找到这个九十九,让九十九啊排到整个最后边。 好,那这个时候呢,呃,我们首先是拿前两个数进行比较啊,好,五十六和三十四进行比较,那因为左边大于右边。好,那我们呢,让这两个数值交换位置 就变成这个样子了。好,那接下来,呃,我交换之后的这个五十六再和他后边的这个值进行两两比较, 五十六又比二十五大,所以呢,五十六和二十五也就是左边大于右边啊,交换位置。哎,那就变成这个样子,再接着啊,五十六和十二进行比较, 左边大于右边交换位置啊,那再接着啊,五十六和九十九比较,这个时候呢,左边不大于右边了啊,啊,左边小于右边,那这个时候呢?两个数不交换位置,那这个时候再继续比较,两两比较,我就用九十九 啊和十一去比较了,那左边大于右边交换位置啊,好,那这个时候九十九再和八十去比较啊,那九十九大于八十,左边大于右边交换位置, 再接着我们用九十九和十四去比较,左边大于右边交换位置。哎,这第一轮我们就确定了在八个数值当中的最大值九十九。 好,那第一轮完成之后,我们第二轮应该是在七个数字之间找最大值,那这第二轮在七个数字之间找,我们还是和刚才的套路是一样的,两两比较, 三十四和二十五比较,三十四大于二十五,左边大于右边交换位置,然后我们用这个大值,也就是三十四和十二比较左边大于右边交换位置,三十四和六十五比较啊,左边不大于右边不交换位置保持不变。那接着我们用五十六和十一去比较左边大于右边交换位置, 五十六和八十比较不交换位置,八十和十四比较交换位置。哎,第二轮就结束了,我们就得到了 第二轮的最大值。那有一个细节呢,就是第二轮其实我们少比较了一次,因为那九十九已经被确定为最大值了,所以我们八十就没有必要再和九十九比较了。哎,减少一次比较啊。 好,那第三轮开始还是二十五大于十二交换位置,二十五和三十四呢?不交换位置,三十四和十一交换位置,三十四和五十六不交换位置, 五十六和十四左边大于右边交换位置。第三轮好结束,我们确定了五十六在倒数第三的位置。 好,那再接着下一轮就是第四轮了啊,好,第四轮两两比较,十二小于二十五不交换位置, 二十五和十一。左边大于右边交换位置,二十五和三十四,左边不大于右边不交换位置。三十四和十四比较左边大于右边交换位置。第四轮结束。哎,我们刚才在五个数当中找到最大值三十四。啊,好, 那因为每一轮,比如说我现在是第四轮,那我第四轮就意味着前边已经决定了三个最大值了,所以我就减少了三次比较。 是这么个意思啊。好,那现在还有四个值,我们快点,十二和十一交换位置,十二和二十五不交换位置,二,十五和十四交换位置。哎,好,然后我们再进行下一轮啊, 来,那这个时候十一和十二啊不交换位置,十二和十四不交换位置。好,这是第六轮,然后第七轮,十一和十二不交换位置。哎,十二就确定了 啊,那没有第八轮啊,因为只剩下呃,十一一个数值了,对吧?好,那就 ok 了。哎,这个就是我们的冒泡排序法啊。好,那,呃,如果你没有太明白呢?还可以把这个视频呃导回去再重新看一下啊。那接下来呢,我们就来写代码,用我们的代码来实现它, 那这几个数呢?我们把它用列表来表示啊,那列表之后呢?然后我们用 l、 e、 n 呃,去求得它的元素个数,那我这个变量就是 l n 元素个数啊, 好,那我们知道它就应该是八,那接下来我们否应去循环多少次呢?注意,在这润之,我写的是 l n 减一。 为什么减一啊?那其实在我刚才动画演示当中我有提到,那就是我八个数,其实我要进行七轮的查找啊,剩下一个数自然就是最小值了啊,所以我们在这论之是 l n 减一啊,当然我们知道 l n 是 八,这减一呢就是七, 当然,呃,这还有一个细节,就是我们这个 n 啊,就是 foring 这个 n, 它的值取值,它应该是零一二三四五六。那在后边我的表述当中,我说第几轮比较,那我会说第零轮,第一轮,第二轮啊,一次啊,是这样去表达啊。好, 那接着我们这个 for in 这个外层循环,决定要执行几轮查找,然后每一轮查找当中,我要在这轮当中找到最大值,所以我又写了一个循环 for 啊,然后这个润质还是 l n 减一,那这个时候这个 l n 减一又是什么意思呢?因为假设说我第一次是有八个数字,那实际上呢,我要比较七次,就是其中一个数字和另外七个数字进行比较, 我就能得出来最大值是多少,对吧?哎,是这个意思啊,好,那当然啊,我在这呢有一个优化,就是我们第啊,这个第一第零轮的时候啊,因为一个数值都没有, 这个找到就是一个最大值都没有,所以呢,那我们肯定是要七次,但是第一轮的时候我已经有一个最大值了,那我是不是就应该少比较一次啊?那第二轮的时候 我已经有两个最大值了,那我就应该少比较两次,所以呢,第 n 轮的时候我就应该少比较 n 次 啊,所以我在这再加个减 n 啊,我的意思啊,你第几轮就是找到几个最大值了,所以第 n 轮就是找到第 n 个最大值了,那我这个比较的次数呢?你已经找到第 n 个最这个这个 最大值了,我比较次数就应该减 n 啊,是这么个意思啊,第 n 轮减去已排好的 n 个数, 哎,这个是内层循环,到底循环多少次?在这有这么一个值啊?好,那当然,这这个内层循环的这个 a 啊,那它取值肯定也是从零开始啊,零一二三四五六,最大是六啊,是这样, 好,那这个时候里边的代码如何去写?根据我刚才动画的讲解,那就是两两比较,两两比较呢?那其实呢,就是前边一个值啊,就是这个列表里边的 i 和他紧挨着后边的 i 加一进行比较, 如果左边大于右边,也就是 i 啊,这个大于 i 加一。好,是这样的啊,左边大于右边,那这个时候 这两个数值交换位置是这么个意思啊,好,那交换位置我们怎么写啊?是这两个值交换位置啊,就是 a r r 方括号 i 和 a r r i 加一 就是我。我前边和后边紧挨着吗?这两个值如果是左边大于右边交换位置,那我们的代码呢,是这样去写啊,这个是拍算当中的一个简易写法。 那无非是呢,呃,等号啊,等号左边呢,我把 i 加一写在前边啊, i 加一,逗号 i 是 这个样子啊, 也就是说呢,现在等号的右边是左右啊,这个样子啊,好,那等号的左边呢,那就是这个样子,变成右左,这个时候其实这两个列表当中这两个值就交换位置了啊,是这样啊,好, 那交换位置完成之后,我们只需要在循环之外打印一下这个列表就可以了啊,好,这就是他的全部代码,代码不多啊,关键的就是说为什么减一啊,为什么减一又减 n 呐,哎,然后怎么去交换呀?那我这个判别是左边大于右边。 好,我们看我实际的这个代码啊,那我执行完成之后再打印这个列表,那这个列表就是从小到大的一个顺序了啊,证明我这个代码是没有问题的啊, 好,那这节视频呢,我们就讲这么多,下节视频呢,我们再去讲一个和这个冒泡排序相关的练习题啊, 好,因为偷车,所以简单,我是讲师井水。呃,这个呢,还是和蟒蛇书没有关系啊?因为这个还是一个同学的问题,这个视频如果你有什么疑问,欢迎在评论区留言讨论啊。当然你有自己的看法也可以在评论区留言啊。好,呃,那让我们下个视频再见。

比如说那个什么淘宝呀,字节啊,那种大的网站,他们如果说优化一下,提高一倍的这个效率,他得节省多少钱,对不对? 哈喽,大家好,这里是熊猫编程,今天是二点三节末尾排序啊,前几天呢,有点事啊,给大家好久没更新了,今天呢,终于抽出时间来给大家更一期,那今天我们讲什么内容呢?主要讲一下末尾排序的基本原理与优化。我们先来看一下基本原理啊,给大家准备了一个注示, 那末排序的基本原理,如果总结出来的话,首先我们如果想要从从小到大排序的话,那么我们就从左往右,便利这个数字元素,然后两两比较, 然后如果这个左大于右了,那这不就是我们一种错误的顺序,对吧?因为我们希望是左边小右边大,如果顺序错了呢,我们就交换他们两个的顺序,这就是它的基本原理了,简单说就是两两比较,逆序就交换。 我我们不好理解的话呢,给大家举了一个例子,比如说这个数组非常简单,一共有三个数字啊,整数的一个数组三一二,这是三个元素,对吧?那么我们两两比较,从左往右就是先比较三和一, 那么显然他现在这个顺序是错的,对吧?因为我们想要的是从小到大,他现在呢是左边大右边小了,那么就交换一和三的顺序,那交换完了之后呢,这个数组里面就是一三二了,对不对?就是零号和一号比较完了,一号是不是和二号要比较了,那么三和二一比较,哎,发现 还是左边大右边小,也是顺序是错的,那我们再交换,交换以后呢,就变成了二和三,那这样的话呢,它的顺序就变成我们想要的这个从小到大的顺序,那就是排序完成,这就是排序后的结果 啊,其实这个非常简单,对吧?那么我们下面呢,知道了原理之后,我们写一下这个代码啊,这个代码的基本构成呢,是两层放循环里面呢,有一个 f 判断啊,大家先记好这个基本判断啊,我要强调一下啊,这个冒泡排序是我们学编程非常重要,非常经典的一个 这个算法,这个大家要背过的。好,那我们开始写代码,首先呢,我们先准备好一个数组,我们准备一个整形的数组,长度呢是五,它简单一点啊,我们给他一个四呃,三五一二啊,把它不要弄得太特殊啊,弄得普通一点,然后两层负循环,负 int i 等于零, i 小 于这个地方呢,我可以直接写五,对吧?但是呢,其实有一个好的习惯,就是我给大家强调一下啊,我这里准备一个 n 变量,它的值呢,我给它复制一个五,那这个 n 呢,就表示的是数组的 啊,长度,对吧?什么叫数子的长度呢?就是数组里面有几个元素,这个数子有五个元素,所以它长度是五,那么你们就知道了,这地方为什么写五呢?是因为它的长度是五啊,同学们,所以我这样写呢,是比较通用一点,让大家好理解,否则我这里一会五啊,六啊十啊的,你不太理解为什么小于这个数,注意是小于它的长度啊,那以后我们会面对各种各样的 不同的数组,那么这个地方你就写它长度就可以了,来 i 加加,对吧?这就是我们可以便利数组随着 i 从零开始变化, i 的 值呢?零一二三四,对吧?它是小于五的,它取不到五,零一二三四,你看零号元素,一号元素,二号元素,三号元素、四号元素,它是不是就能取到每一个元素了,对不对?那么这个 i 呢,就是下标 啊,什么是下标?大家理解对吧?前面讲过了,数字的下标,通过数字名加下标的方式呢,可以访问数字里面的元素,这个是之前讲过的内容,然后内层呢再写一个负循环,这个时候就要变一下这个变量名了。刚才用的是 i, 我 们一般呢里面呢就用 g, g 的 话呢,也是从零开始,然后呢 g g, 注意这个地方是小于 n 吗? 我们要思考了对不对?因为假设我们自己要去发现这个地方是小于 n 吗?我们要思考了对不对?因为假设我们自己要去发现这个地方是小于 n 吗?好, 那么我们小于 n 以后,我们学着这个外层循环呢,也去给它加加,那么看起来呢,现在很正常,你看外层循环零到四,内层循环也是零到四,好像没什么问题,对吧?但是不要忘了我们刚刚说, 哎,里面要干嘛呢?里面要两两比较,如果左大于右就要交换顺序,这个我们现在还没写,对吧?这个是一个非常关键的一个操作,那我们就在这个内层循环里面写个 f, 判断一下它是否是一个错误的顺序,也就是是否呢左大于右, 那这个左和右是指的什么呢?是指的下标的关系,对不对?下标零就在一的左边,一呢就在二的左边,我们是这样 来分左右的,对吧?那我们判断的时候呢,就用下标来判断, a 中括号 g 数组名加下标,是不是就能代表一个元素啊?对吧?那 a 中括号 g 就 代表了 g 这个下标上的这个元素,那么如果它大于它右边是谁啊?同学们, 就是现在下标 g 的 右边的这个元素,下标是几呢?你看四是零号元素,它的右边是不是一号元素啊?所以说 这个 g 这个下标,他右边的下标是 g 加一,大家能理解吧?这个很好理解,对不对?我写个注式啊,就说其实这个注式我刚就写好了,就是如果左大于右,是不是我们现在是不是在进行这个判断?如果左大于右了,我们是不是要干嘛?进行交换顺序了,对不对?交换顺序这个我们先不说,我们先要看什么,就刚才老师问大家说这个地方是小于 n 吗? 小于 n 会不会出错呢?你看会出错,对吧?为什么?因为我们这个 g 呢?是加一的,当我们这个 g, 你 看它最大取到几啊?零一二三四,它小于五,它能取到四,对吧?它取到四的时候,四加一就变成五了。 我们这里有五号元素吗?零号、一号、二号、三号、四号,没有五号元素,我们没有五号元素,你去取这个五号元素,那么它就会越界数组下标越界,它就会报错啊,所以说这个地方你不能跟这里一样啊,内层呢,要减个一, 这是给大家要强调的,大家明白了吗?经过我这样一讲,大家应该明白了,为什么这里减一,就是因为这里加一了,对吧?他取不到四,他取到四的时候加一变成五就超了,对吧?所以说这个地方加一了,这个地方就要减一 好,那这个地方为什么加一呢?就是因为左边是 g, 右边就加一嘛,对吧?明白吧?啊?因为左和右就是 g 和 g 加一, ok, 那 这里明白了以后,我们下面接着写这个交换顺序,交换顺序这个地方要注意什么呢?我们要 利用第三个变量去交换,大家想一下啊,我如果说这是零号元素,这是一号元素,我直接把一号元素复制给零号元素,那这里变成三了,四就消失了,对不对? 你四消失了一会我怎么把四再给三呢?我要先把这个四存起来,我不能直接把一号元素复制给这个位置,这边我们之前讲过,他相当于一个这个格子,或者是你想象成一个用铅笔在纸上写字,如果你把这个变成三了以后,那个四跑哪去了?四是不是就消失了呀? 所以说我们在它消失之前,我们先要把这个四存起来,再把三给四,然后再把刚刚存起来那个四放到这个位置,所以说我们要借助一个另外一个变量暂时存储一下,一般呢我们叫 t m p, 为了大家简单呢,我们就叫 t 了,好不好啊?这里呢,我尽量给大家,已经是最简化了 来,那这个 int 呢?就首先记录一下我们一会将要被覆盖的这个变量,就是 g 这个变量,对吧?然后我们就可以放心的给它赋别的值了,因为有不怕了,对吧?它别的值给它以后,它原来的值已经被我存起来了,所以就不怕了,我们就可以把这个 g 加一的值复制给它,然后呢再把 g 加一的值里面, 这个 g 加一里面存什么存?我们刚刚是不是保存起来这个 t 啊?你看这样倒腾一下,那么 g 和 g 加一左右呢,就互换了,明白吗?我给大家举个例子啊,比如说 t 现在等于四,然后呢三放到了四原来的位置,对吧?然后 t 呢?再放到了三原来的位置,这样的话就实现了一个交换啊,那大家可以停下来在纸上画一画,然后呢感受一下这个交换是怎么完成的, 一会老师会给大家画图啊,但是讲的是整个排序的过程,不会讲的太细啊。好, ok, 那 么我们写完了,写完了以后呢,其实就开始交换呀,然后一个一个的比较交换,最终这两层负循环都执行结束以后,在这里我们就可以干嘛呢?就输出,看一看 输出数组的元素,我们看看它是否排序成功了呢?那怎么输出这个数元素?其实就是便利,对吧?那便利呢?就是用到否循环 int i 等于零,然后呢 i 小 于 n 啊, i 加加。那这个地方老师有同学可能会问,老师,我刚刚用过了变量 i 啊,这里又用变量 i, 他 又声明了,又变,他两个会不会就是说重复声明会报错呀?注意, 那这个知识点呢,其实是一个关于局部变量的作用域的这么一个知识点,当然这么讲可能有点大家可能不太懂,你就理解成这个变量,它的存在范围只在这个方循环里面,除了这个方循环,这个 i 就 不存在,那么同样的这个 i 变量呢,也是只存在这个方循环里面, 他两个互不影响啊,各自有各自的地盘,对不对?所以说他两个没关系啊,不会报错,放心用啊。然后我们输出一下数组名中括号加下标,就可以得到这个数组中的元素,我们后面呢跟一个空格来优化一下格式好了,我们保存一下,然后呢检查检查,大概检查检查啊,差不多应该没什么问题啊, 来我们编辑运行好,大家看是不是这个一二三四五就出来了,对不对?那我们就成功了,那这是第一步, 这是第一步,但是呢我们要讲的肯定不止于此啊,同学们呢,可以暂停,先去自己完成到这一步,先练一下。然后呢我们要给大家讲一下怎么去优化这个代码,好不好? 好的,下面呢我们画图给大家讲一下这个冒泡排序的比较过程。我们刚刚准备的那个数组中,五个数是四三五一二,对不对? 那我们第一轮开始比的时候要遵循这个过程啊,从左往右两两比较,然后呢逆序交换,那么现在就开始了,两两比较,对吧?从左往右,那么就是他两个先比,他两个一比,是不是左大于右呢? 对,满足了对吧?也就说左大于右了,需要交换了,那么交换过来以后就变成了三四五一二,对吧?好,数组中他的这个数据啊,在随时变化, 交完了以后,我们是不是该挪动了,对不对?挪动这个时针了,或者挪动这个下标了,然后呢该轮到他两个比较了,他两个是否满足左大于右呢?他两个是不需要交换的,对吧?本来四就是应该在左边,五就应该在右边,好,他两不用动,不用动。然后我们再比较这两个,这两个是不是左大于右,需要交换了?哎?交换一下三四一五二,然后再比较谁他两个对不对? 他两个是不是也需要交换?因为左大于右了?好,然后交换三四一二五。好,那这样的话呢,就是第一轮 就完事了,就从左最左边到最右边,这是一轮就结束了。一轮结束以后,大家发现啊,是不是五这个作为这个最大值,他是不是跑到了这个最右边啊? 哎,你发现一会这个规律会再次出现啊。然后我们进行第二轮时针呢,又回到了这个最左边,然后呢再开始比较,前两个就是三和四,但是三和四你发现,哎,不需要交换,好,那我们就继续往后再找两个,就是四和一,四和一,是不是需要交换了?那这个时候就是三一四二五,其他的不动啊?因为我们只交换了这两个,其他没有变。然后呢, 我们再继续该谁了?四和二,四和二,比较一下,需要交换,那就是三一二四五。好,然后再比较四和五不需要交换。那么这个第二轮呢,就结束了,就是从最左右到最右又来了第二轮,然后我们继续第三轮。 第三轮的话,我们比较三和一,那三和一需不需要交换呢?需要。那就是写到右边啊,写到这,然后一三二四五,对吧? 然后呢该比较谁了?该比较这个三和二了,然后交换一二三四五。注意啊,我们人呢,肉眼一看就知道现在已经这个比较完了,但是你说计算机知道吗? 刚刚我们写的代码来看的话啊,这个代码当中是没有判断的,所以说计算机现在并不知道已经完成了这个排序的任务,已经是 ok 的 了,他不知道,他就会继续比较,哎,三和四是否需要交换呢?不需要。四和五需不需要交换呢?不需要。那么这个时候呢是第三轮, 他会不会第四轮,第五轮呢?他会的啊,同学们,他还会继续再比较一一二二三三四四五,然后再比较一二二三三四四五,一共几轮呢?因为我们的外层循环这个是零到四,对不对?所以说呢,他会需要进行五轮,对吧?他会五轮。那么这个过程呢, 就是我们刚刚写的代码的整个过程,其实到这一步的时候就已经排序完了,对吧?你看而且他的规律什么呢?他第一轮的时候五到了最右边就是已经排序好了,是最大值。然后第二轮的时候呢,换个颜色啊,你看是不是四五已经准备好了?第一轮的时候是一个最大值,第二,第二轮的时候呢是最大值和四大值。第三轮的时候呢,当然这里比较特殊了,就是本来是这个最大 和第二大,还有第三大的排序好,但是我们这个题呢,又特殊了,它是全排好了,对吧?然后我们这个为什么叫冒泡排序啊?其实呢,它就像在水底往上冒泡一样,对吧?这个大家学过物理知道啊,这个压力,这个水的压力的关系,气泡呢?在从下面往上面这个 这个漂的过程当中呢,它的体积会变得越来越大,对不对?其实就相对于我们这个最大的这个数呢,像一个气泡一样,它先冒出来,然后呢第二大的,然后第三大的,第四大的,这个就是冒号排序,它名字由来,这个它当然不重要啊,关键就是我们理解它的这个原理,就是从左往右两两比较,逆序交换,这个原理你背过了,你才会知道怎么去写代码, 嗯,这个是重要的。然后我们刚刚给大家说的一点是什么呢?明明在这个第三轮的时候就已经排序好了,但是呢它还会 进行两轮的多余的工作,那我们接下来的这个工作呢,就是希望能优化下这个代码。还有什么呢?就是每次你看我既然知道这个规律,就是每次他两个数已经有序了,那我们是不是第三轮的时候就没有必要再去比较四和五了? 包括第四轮如果还没有排序好的话,那么我还没有必要去比较三和四和四和五了。所以说我们每次不一定是从最左到最右,有的时候我们就是从中间就可以停了,就最右边已经是有序的了,就没有必要比较了,这也是一个可以优化的点。所以说冒号排序虽然很简单啊,但是里面所蕴涵的一些原理啊,算法的这种概念 还是很多的,值得大家去反复的去复习,反复的去琢磨。那下面呢,我们就写一下优化的代码。好,那刚才呢通过画图给大家讲了一下,为什么我们要进行优化,以及我们优化的方向是什么?我们优化的方向呢,一是减少他的轮次, 二是呢他每一轮的时候我们没必要从最左到最右,对吧?我们可以少比较几次,其实这是两个方向,对吧?这是两个方向啊,一个是减少轮次,一个是减少他每一轮过程当中比较次数,对吧?就减少, 那我们这是刚刚的那个代码啊,我们想要减少比较次数,那我们是不是要有一个参照啊?我们先要知道现在我的比较次数是多少,然后一会我优化完了以后,我看一看我是否减少了,对不对?那好,那我增加一个变量,叫做 count, 那 这个变量呢?就是用来统计的计数器,那 count 一 开始是零,然后呢?我每次比较一次,是不是到了这里就发生了一次比较,那我就在 f 的 上面,然后让这个 count 呢? c o、 u、 n、 t 让它加加,这个呢就是表示的是什么?是比较的次数对不对?哎?它表示的是比较次数,然后等我们循环结束以后呢,我们输出一下,哎,比较了 啊, c、 o、 u、 n、 t 这么多次,对吧?哎,我们换个行,这样的话我们看一看啊,在优化之前,我们这种普通的初级版呢,它一共比较了多少次 来变异运行,注意看啊,我们此时呢是比较了二十次,对吧?啊?大家能看见吗?比较了二十次啊,注意,这是普通版的,没有优化的啊,我们放在这, 然后我们现在开始优化。优化怎么优化呢?就是我首先优化一个简单的朋友们,我是不是没必要每次都从最左到最右啊? 因为我们刚刚发现他每一次的每一轮两个有序,第三轮三个有序,我们每一次其实没必要到最右, 每次呢,就是每一轮的时候呢,其实是要少比较一个的。那这个地方啊,就说第一轮的时候少比较一个,第二轮的时候少比较一个,第三轮的时候少比较两个,是不是这样的呀?所以你发现没有?哎,这个地方其实是跟我们的 i 变量有关系的,跟轮次有关系,第一轮少比较零个,第二轮少比较一个,第三轮少比较 啊?两个,是不是这个 i 的 增加,就是我们这个 i 变量逐渐增加,是不是就是我们每次少比较的那个次数啊?就是 j 变量,每次没必要取得那么大了,你少取几个对不对?你只只比较前几个就可以了,因为后边已经有序了,我这样讲大家能理解吧? 好,然后我们其实就加了一个减 i, 但是这个减 i 呢?它对我们的这个优化啊,起到了非常大的这个作用。来我们看一下啊,只增加了这么一个减 i, 其他的都没有动,然后我们再编辑 运行,你看这次刚刚是不是二十次啊?你看这次他只比较了十次,我们的效率整整提升了,可以说是一倍。 那大家想想,这只是五个数字的一个非常小的一个循环,他就提高了一倍。那你想同学们,如果说是一个非常大的一个系统,比如说那个什么淘宝呀、字节啊那种大的网站,他们如果说优化一下,提高一倍的这个效率,他得节省多少钱, 对不对?所以说这个优化程序是非常重要的一种思想,大家要重视起来啊,不要说哎,能完成任务就行,有的时候这个优化很重要,很重要啊, 那这是第一种这个优化的思路,我们已经完成了,那么第二个优化思路就是我不希望他已经排好序了,还进行无用的比较,就刚才那个明明第三轮的时候已经一二三四五了,但是他还会进行第四轮,第五轮的这个比较,那不是在浪费时间吗?对不对?那这种怎么优化呢 啊?我也不卖关子了啊,我直接给大家讲,我需要再定一个新的变量 flag, 一 开始呢他的默认值我给他一个,呃,这个我可以不在这里复制啊,我就是定义一下在这里,然后呢我在哪呢?我在这个外层循环的里面啊,内层循环的外面就他两个之间 啊,我定我干嘛呢?我让他的值等于一个零啊?给大家解释一下啊,这叫做标记变量,就是 flag 这个单词本身呢,是标记的意思啊啊,然后我们零代表什么意思呢?零代表没有发生交换 啊,零代表没有发生交换,那么当我们发生了交换,是不是这里发生交换了?当我们发生交换的时候,我们就让这个 flag 呢? 等于一,哎,这个表示什么?发生了交换,就是我们一开始我们默认的认为它没有发生交换,但是呢一旦发生交换以后呢,我们就修改这个变量的值,这样的话,等循环结束以后,我通过判断这个 flag 的 值,是不是我们就知道这个整个的这一轮啊,不管是第几轮,第二轮、第三轮,这一轮从左到右有没有发生交换, 如果说没有发生交换,说明是不是已经有序了,因为只有有这个错序的顺序错乱呢,才会发生交换,没有发生交换是不是就表示现在完全的整个已经都是有序的状态了, 那么是不是就 ok 了呀?是不是可结结束这个排序了呀?对不对?大家能理解吧?所以说如果 flag 等等于零的话,表示整个的这一轮都没有发生交换,顺序已经全部 ok 了,那么我们就 break 结束,外层循环,就整个循环全结束了,对不对啊?整个排序就结束了, 大家能理解吧啊,这个我讲的应该很仔细了啊,好,那么这个我们优化完成以后呢?老师呢?顺带的优化一个小小的地方,这个不是很重要啊,就说我们最好不要每次创建一个新的变量,我们可以在外面呢去声明它,那里面呢?只是使用它啊,就不要在里面去声明,当然这个影响不是很大啊,只只是一种好习惯 啊。 ok 呢,就全部结束了,那这我们再去编一行,看看这次我们的比较次数是多少, 哎,这个有点失望,对不对啊?那刚刚我们优化了一下,就提升了这个一倍,对吧?效率提升一倍,那么这次为什么一点变化都没有啊?白优化了是不是啊?这个地方呢, 不是白优化啊,因为我们这个情况呢太简单了,体现不出来啊。我们给大家准备一个别的例子,让大家感受一下,你就明白了,比如说 准备一个极端一点的啊,我现在呢已经是一个有序的数组了,注意看啊,我,我要的这个数组就是从小到大,但是我现在呢,已经是一个从小到大了,对吧?就是斗一下这个电脑,对吧?斗一下这个计算机,我,我要的是从小到大,但现在已经是一个有序的了,其实你不用 做任何工作就完事了,对不对?但是如果是原来的话啊,如果是原来的代码呢?我没有删啊,这是原来的代码,对不对?好,我放在这 把这个第十四行注视掉,这是我们刚刚的优化之前的代码,那我们优化之前的代码它会比较多少次呢?拿过来啊,放在这,这个是没优化之前的啊,那么这个当然要给他一个 ctrl 好 了,来我们看一下啊。这个 ctrl 在 哪加加来着,还记得吗?哎,在这里加加,对吧?好,来我们编辑 运行啊,其实不用看了,对吧?这个我们应该记住了,二十次,对吧?那但是注意这个二十次指的是什么?指的是我已经更新了新的这个数值了,一二三四五,你发现不管是什么数值,就是已经有序的也好,还是说乱序的也好,他是不是都比较二十次啊?这是没优化的啊,来,这是优化了的啊,那优化了以后一二三四五,他是不是 根本就什么都不用干啊,对吧?好,来,我们变异运行,那么他比较了几次呢?你看他这次只比较了四次,是不是其实是优化了有有效果的,对不对?那么为什么还会比较四次呢?就是因为你看一二, 然后二三,然后三四,然后四五,他是不是这样比较完四次是不就知道了?哎,一次交换都没有发生一次交换都没有发生,说明他已经有序,对不对?一次交换都没有发生,那么就结束了, 大家明白了吗?所以说我们这个优化啊,不是说没有效果,而是说你要看你这个数组优化以后有没有产生这个区别,那那种有的时候呢,确实没有发生区别,但是呢它并不代表这种优化没有意义,这种优化是很有意义的, 明白吗?那到此为止呢,我们就讲完了冒号排序的基本原理和优化。这个冒号排序呢是需要大家背过的啊,要非常熟练的写出来,包括这个地方很容易记错的这种优化 啊,就是简 e 简 i, 还有这个 flag 的 这种标记变量的使用啊,这都是非常非常经典的必会的代码啊。希望大家呢好好的去练习。那么今天的课程呢,就到这里,我们下节课再见。拜拜。

通过这位同学提供的练习题,呃,可以让我们更好的理解这个排序,也就是冒泡排序。好,那我们来具体看一下他提供的这道题,以及我们看一下他的正确答案啊。 好,那首先呢,这道题给了我们一个八个数的列表,然后呢,我们第二行代码就可以获取这个列表的长度,那此时 n 应该是八, 如果说我们进行冒泡排序,应该进行七轮八减一,所以我们的代码呢,那也就是 n 减一轮啊,这是一个润指啊。好,那 n 减一轮之后,每一轮我们是让两两个数进行比较,然后呢,最大的值往后 移动啊,是这么个意思啊,好,那两两比较,八个数也应该比较七次,所以呢,我这呃内部循环还是 n 减一只。不过呢,如果说我第零轮,那我只是把零个最大的值找出来,那如果 i 是 一 啊,是第一轮,就表明是说我已经找出了一个最大值了,那我在内部循环比较次数的时候,就应该少一次啊,少比较一次,那如果我 i 是 三呢,就证明说我已经找出来三个最大值了啊,那我在内部循环量量比较的时候,我就应该少比较三次, 所以这个循环有一个减 i 是 这么个意思啊,好,那针对于这个同学这道题啊,他有一点小坑,这么一个细节,在我讲的视频当中是 如果左边大于右边怎么怎么样?但是同学这道题呢,他写的是小于啊,这是老师布置的作业啊,应该是这么一个小于啊,这小于意味着什么? 首先这个是说左边小于右边,那当然,如果左边小于右边,他后边的代码还是交换位置,那将意味着什么 啊?原本说如果我左边小于右边,也就是呃,左小右大啊。好,那如果说满足这种条件,他之后的代码是要求两个数交换位置,那就变成了, 呃,左边是大,右边是小啊。那如果反复这样去比较,那最终的结果最小值反而是排在最右边 啊,或者说这个列表的最右边最后边。所以呢,在整个完成这个代码排序之后,那这个列表里边的值,它就应该是从大到小排序, 而不是从小到大啊。我在上一节视频讲这个具体的排序的时候,默认是从小到大排序的,而现在就因为这么一个小于号啊, 这么一个改变啊,这么一个小细节,那么排序的结果他就应该是从大到小。哎,这是这一道题的一个考点啊。好,那我们再看他继续里边的这个代码,就是让呃左右两边的这个数值交换位置,他怎么写的 好。那首先呢,呃,这个蓝色的部分啊,是左边,就是 n u m s 方括号 j, 对 吧?这是左边的值啊。好,它先把它保存到一个 t e m p 临时变量当中,那保存到临时变量当中之后,那就意味着 n u m s 方括号 j, 也就是这个蓝,呃,蓝色的这个呃值,这个变量 它就可以被其他的值覆盖了。哎,所以我们第二行呢,用其他的值给它赋值,这个其他的值是红色或者说粉色的这个,也就是右边的这个值给它赋值。那此时蓝色里边啊,这个色块里边保存的是右边的值了啊,那我粉色的这个部分呢,其实还没变,对吧?好, 那我之前把左边的那个变量的值保存到 t e m p 里边了,此时我再把 t e m p 这个临时变量的值啊,赋值给 粉色的。哎,这样呢,就实现了蓝色和粉色这两个变量之间的交换啊,它们值的交换啊,是这意思啊。好,那当然呢,我在上节视频写的是一个,呃, python 当中的这么一个简洁的语法啊,是这个样子 啊,那就是我们等号的右边是原本的左右啊,是这样一个原本的顺序啊,那我只需要说赋值等号呢,然后等号左边我给它变成右左,哎,就这一行代码,就这么简单就让左右两个变量它们的值 互换了啊,就这么个意思啊,好,我这样去写,是因为我这个 ppt 需要空间,所以呢,我们就用这种简写的形式,不影响我们的分析啊。 好,那最后一行代码,那无非就是说整个这两层循环结束了,我们打印一下排序之后的内容啊。我再重申一遍,因为这个 if 那 条语句,它不是左边大于右边,而是左边小于右边,所以排序后是从大到小排序的啊。好, 这个呢,就是这道题,那么我们看一下具体的选项, a, b, c, d, 那 其中 a 呢?说程序共进行八趟排序是排序最优趟数减, 其实前半句就错了,因为我刚才有提到,我们如果说对八个数进行排序,那其实他只需要七趟啊,最后剩下那个值,他必然是,要不然是最小的,要不然就是最大的啊。好啊,那当然呢,我们还是深入一些啊,他说是排序 u 啊,最 u 趟数减,这个也是不对的啊,为什么呢?如果说你有认真看我上一节视频啊,当然你没有看也没有关系啊。好,那其实呢,当中有这样的一个啊,过程,这是过程当中的一步啊。好,我们看一下。那,呃,九十九,也就是最右边这个是 i 等于零的时候那个循环 啊,得到了,他找到一个最大值,然后 i 等于一十,找到他 i 等于二十,找到他 i 等于三十,这 i 等于四十,是,这,好,那在这就有一个特殊的啊,那就是说到此时的时候,其实我们看这个图形, 整个这个列表,他已经是从小到大排序了啊,也就是说其实我们不需要再进行循环啊这个排序了,但是呢,他还是傻傻的按部就班的把这个该循环的循环完啊。 好,那我们既然看到有这样一个现象,这个就说明我们可以有优化的空间,那具体的优化我们怎么去做呢?哎,我们可以在呃 内部循环之前说,这次我要找一个最大值或最小值了。好,那在之前我先定义一个变量 flag 叫标志位啊,我默认给它一个处这么一个值啊。好,然后内部循环,也就是说两两比较,我找到最大值或最小值啊,这个样子,当然不管是这两两比较是最大值还是最小值,如果它交换位置好,那我呢就让它 flag 等于 false, 那就说明什么等于 false 就 说明。哎,这个之前这个列表它还不是一个完美的竖列,它既然能够交换位置,就说明它之前不是从小到大或从大到小啊,啊,它不完美,所以呢,就是 false, 是 这么个意思。当然反过来说,如果说 这个内部循环执行完了啊,每一次 if 判断都不成立啊,那也就不会执行 false, 那 就意味着这个列表啊, 里边的所有要排序的数字,它已经是默认你想要的那个顺序了。针对于我当前这个代码来说,那它就已经是从大到小了啊。如果说针对我们默认的那种写法,它就是已经从小到大了,它已经是一个完美的顺序了。 好,它就不会不会这个付用 force 复制这个标志位了,是这个意思啊,所以那在内层循环啊,结束之后, 哎,我们在这,那如果这个 flag 为竖的话,哎,我刚才说了啊,如果它为竖,就证明,呃,内部循环没有发生交换,内部循环没有发生交换,就意味着我们整个要排序的这些数字,它已经是排好的了的啊。好,那既然已经是排好了,那 剩下我不管剩下多少轮还没有比较,哎,我都提前结束掉它啊,就没有必要再白费功夫了啊啊,事实,如果你是处,那就证明了你已经是排好了的,所以就执行了一个 break 啊,打断中指这个循环啊。好,这个就是这么一个优化的步骤啊。好, 那回来。所以呢,哎,这个前半句很明显很简单就能判断出来啊,然后他是不是最优趟数解这个呢,也是不对了,所以这个就错的很彻底了。好,那第二个选项,他说当 i 等于零时排序后, 其实说白了就是排了一轮了,那按照我对这代代码的分析,他应该是从大到小,每一次比较应该是找到最小值, 所以在 d i 等于零这一轮排完序之后,最小的值应该在列表的最右边啊,那我们看到,其实呢,也就是说整个列表当中,十一是最小的,十一应该在十四这个位置,而他现在十一啊,排在倒数第三的位置,所以这个结果就是错误的啊, 所以呢,这个 b 就是 错误的啊。好,那选项 c, 他 说第二趟,也就是 i 等于一的时候啊,排完序了,这两轮已经排完了,那就是说两个最小的值应该在列表后边,那我们看一下。 哎,差不多啊,十一十二,从大到小排序的话,那这个应该没有问题,所以在这呢,应该是正确了。我没有给实心的这个绿这个对勾,为什么? 因为剩下的值确实是这个顺序吗?不一定,那我脑袋里边计算不出来啊,你比如说五十六,三十四,九十九,二十五、八十十四,第二轮 d i 等于一,也就是第二轮之后,他们的顺序确实是这样吗?我不确定啊。好, 然后,所以呢,这个是存疑,然后我们看 d d 呢,他说排序后啊,一看这个排序后是从小到大排序,这就肯定不对,因为我分析了整个这个代码执行完,他应该是从大到小排序, 所以呢, d 肯定是不对的。那现在最后就剩 c 了,对吧?那这个 c 由原来的我半信半疑觉得他对,那现在呢,那他就是肯定的。对啊,好, 那以上就是这一节视频,我虽然分享了全部内容啊,因为透彻,所以简单,我是讲师,顶水啊,那我的蟒蛇书的视频,也就是项目部分呢,目前已经准备差不多了啊,很快就会和大家见面啊,别着急 啊,关于这节视频有什么疑问啊?欢迎在评论区留言啊,当然你有自己的看法呢,也欢迎在评论区说出你自己的看法啊,当然最好能够关注我的这个账号,这个对我很重要啊。好,那我们下个视频见。


哈喽,各位同学们大家好,我是你们的刘老师,今天我们一起来讲一下冒泡排序这个知识点。这个知识点呢,在周天有两个班是在这个月刚学完啊,刚好可以借这个机会来复习一下。 呃,首先呢,我们来讲一下冒泡排序的排序思路,假设现在我们用冒泡排序,对有三五一四二这五个数值 的一个一位数组进行正序排序的话,那他的排序过程是这样的,首先第一轮用第一个数值三 和第二个数值五进行一次比较啊,因为是正序,所以说五比三大,五比三大,因为是正序,所以说他们两个数值不用进行数值交换,仅 接着五和一进行比较。那第二个数值五和计第三个数值一进行比较,发现五比一大参量呢,就要进行一次数值的交换,也就是说第二个数据五变成一,第三个数据一变成 五,紧接着第三个数值五和第四个数值四进行比较,发现五又比四大,所以说依然是进行一次数值的交换,这里的五变成四,这里的四变成 五,紧接着五,第四个数之五再和最后一个数之二进行一次比较,发现五又比二大,那么我们的五啊,第四个数之五变成二啊一,第第五个数之二变成五。 好,那也就是说经过第一轮的北比较和排序之后,那这五一个这五个数值,他的顺序已经变成了三一四 二五。我们不难发现,通过第一轮比较,我们已经找出了整个一维数组中的最大值五,并且把它放到了最后一位啊,最后一个位置。第二轮的时候呢, 我们紧接着还是从第一个数值和第二个数值进行比较,三和一进行比较发现三比一大,那么我们的三和一要进行一次数值的交换, 一变成三,三变成一,那接着三和四再进行比较啊,四又比三大啊,所以说不计不进行数值的交换。紧接着四 和二进行比较,发现四比二大依然是要进行一次数值的交换。那么经过第二轮排序比较排序之后,我们这五个数值的顺序又变成了一三二四五 啊,因为刚才第二轮的时候,呃,第一轮的时候已经把这一个五啊最大数值五找出来了,所以说他倒倒数第二位就可以了啊。那经过第二轮的比较排序之后,我们发现 我们在这一轮又找出了第第二大啊,第二大的指四放在了倒数第二位上,那以此类推。第三轮排序的时候呢,我们找出整个数组中的第三大的指放在第三位上。第四 四轮排序的时候呢,找出整个数组中第二大的值啊,放在正数第二位,呃,正数第二位也是倒数第四位上, ok, 一共如果说一共五个数值的话,我们只进行四轮排序就可以了,因为剩下的一个数值一,他会自动排序号,那也就是说如果说是 n 个数据的话啊,如果说是 n 个数据的话,那他要进行 n 减一轮次排序, 每一次排序呢啊,第一轮的时候我们直接到最后一轮啊,便利到最后一轮。第二轮排序的时候呢,我们直接便利到倒数第二轮, 这到倒数第二个位置,第三轮排序的时候,并立到倒数第三个位置,以此类推。那讲到这里我们话不多说,直接上大码讲解, ok, 这个呢就是我们刚才所讲解的所讲解的这个冒泡排序的 c 家家代码的实验过程。 首先第五行到第八行啊,首先第五行到第八行,这只是这个同学们都已经比较熟悉了,这里仅限一次输入数据 n 啊,代表这一个数组 a 里面有 n 个数值,接着呢用一次方循环, 用一个放循环进行一个输入啊,给这一个数组 a 进行辅值 啊,一共付值付 n 个值,那是一个冒泡排序。这一刻讲解的冒泡排序的核心代码呢,是在第九行到第十九行啊,到第二十行这一个范围,我们一起来看一下。第九行呢, 第十行我们用了一个千套循环,用哎啊变量哎来这一个控制比较的轮数,一共是进行 n 减一轮啊,也就是说 n 个数据进行 n 减一轮次排序来加加, 我们接着来看一下第十一行,十一行的话,我这里用了一个变量 j 啊来控制进行这个对数组里面所有数据进行一次便利,并且进行对他比较,在这里进行比较, aj 等于 aj 大于 aj 和 aj 加一进行比较。这里为什么需要 在这个 n 减 i 的基础上再去减一呢?是因为后面我们这里用的是 g 加一,如果说是只写一个 n 减 i 的话,他后面可能会是可能会出现这一个数数越界的问题, 所以说我们用的是 n 甲 a 减一啊,然后在这里用一个判断衣服的判断进行比较,如果说后 这一个后面的数前面的数值比后面的数值大,那么就进行交换,两个数值的位置进行交换,进行两个数值进行交换的时候呢,我们需要用到第三方变量器啊,第三方变量器来储存一下啊,来储存一下来进行交换的过程。 讲到这里呢,我们冒泡排序的这一个思路啊,以及排序思路以及代码都全部讲解完了,同学们可以在暂停视频理解一下 我们的这个代码的实现过程,从第五行到第二十行,后面的话只是一个输出,没有其他的啊,没有其他的。好了, 没有问题的话,我们就可以先下课了啊。嗯,如果说有其他同学还有问题的话,那可以私信刘老师,再问一下刘老师,好了,下课。

怎么还是排错了?前态循环到底哪错了?你内层循环没减轮次大叔冒完要缩小范围,前态循环是关键,外层轮次内层比较成功了,程序排序又快又准。冒泡排序写程序欠态循环高效验证算法。

冒泡排序是一种极其实用且就业必学的编程算法,其作用主要是用于处理数据,对数据进行由小到大的排列组合 运行原理则就是不断判断列表中有左到右的大小,并进行有序的排列。那么我们要如何使用派放代码来实现这一项功能呢? if 是我们这一节用于判断数组的重要语句, or 也是我们用于便利数组进行排序的重要语句。 除此之外,我们还需要一个数组,就像上面。接下来我们将逐句解释如何给上列数组进行从小到大的排序。以上是我们第一行要写的代码,它没有其他含义, 仅用于定义我们冒泡排序的方法。括号中 list 零则是在这个方法中代表列表的变量。第二行为变量 f 值一个 lin, list 零 lin 在 其中的作用就是判断这个列表中一共有多少个元素,假如有三个元素,则 lin 返回的就是三。第三行开始便利我们的数组, more i in range a 减一。这一行的作用就是便利 a 减一次代码,而 i 代表的是便利的次数。而为什么是 a 减一次呢? a 在 代码中代表的是 数组的长度,又因为如果程序已经给所有的大数字排列完成后,最后一个数字则绝对是最小的一位,程序也就没有进行多余排列的必要了。第四行也是看似复杂,其实很简单。 j 在 这个括号内是作为数组的缩引号,括号中的内容用于确保能便利到数组内的所有需要比较的数字,但是这不是必要的。第三行和这一行的括号内 实写 a 也一样能够达到冒泡排序的效果。第五行,这是整段代码中最核心的部分,这关乎到你是否能够完成排序。以上代码的作用就是用于判断你的数组 list 零中的缩引号 j 的 大小是否大于 list 零 j 加一。 至于为什么要这样写呢?这就需要我们先解释一下缩引号是什么。缩引号通俗来讲就是在一个列表中每一个元素所在的位置,就拿这个数组中的八二来举例子,可以看到八的下标为零,也就说明缩引号为零。 在 python 表达式中就以 list 零零来表示八二则是 list 零一,这样就很好理解。 那至于这行代码中的中括号为什么要写 j 和 j 加一呢?原因就是这个括号内的 j 就是 商异形中括号内的变量,也就是说 j 代表的是数组的缩影号,而 j 加一则就是 j 的 右边一位的缩影号。这么一说 就可以看出这个语句是用于判断数组内 j 的 元素是否大于其右边的元素。第六行,如果上一行的 list 零 j 确实大于 list 零 j 加一的话, 则执行这段语句,将两个元素互换位置,这一段则用于返回在 def 内对 list 零的计算。后续想使用冒泡排序,则可以直接引用这个方法。最后三行分别是,一、 将我们的数组赋值给 list 一 变量。二、用我们定义好的方法去排序 list 一, 并将结果赋值给 c 三、打印出我们的排序结果。以上是我们的完整代码运行结果。 至此,聪明的你已经学会了冒泡排序,谢谢观看。此外,开除速度一定要快。