北大硕士LeetCode算法专题课-基础算法之排序

80 篇文章 2 订阅
16 篇文章 1 订阅

 接连上篇:北大硕士LeetCode算法专题课---算法复杂度介绍_骨灰级收藏家的博客-CSDN博客

冒泡排序

冒泡排序(Bubble Sort是一种很原始的排方法就是过不地交“大”的置达排序目的。 因为不断出现“大数”类似于水泡断出,因被形地称冒泡法。

冒泡算法的基本原理个数的大。将数中较大那个交换靠后位置。

不断地交换下去就可以将最大的那数放队列尾部然后头再交换直到数列成有数列

以数[5, 9, 3, 1, 2, 8, 4, 7, 6]为例,最初的数列顺序如上图所示

第一轮排序:按照冒泡排序的原理比较邻两数字大小。

从数列端开,第1次比76的大小7>676位置把较大那个7交换到后的置。

2次排序比46的大64不需交换

3次排序比84的大4848置位置 第4次排序比24的大42不需交换

5次排序比21的大21不需交换

6次排序比13的大1313置 第7次排序比19的大1919置 第8次排序比15的大1515

第一轮排序结, 成功的将序列中最小的数1交换了队最前

第二轮排序:过程与前一轮类似,然从尾开进行邻两元素比较

当前面的元素比后面的元素大,交两个素的置,二轮序只要进7比较 经过第二轮排序后,数列中最小的个元已经换到列的前面。

第三轮排序:依旧是回到数列的末,重比较邻的个元

经过六次比较后,第三轮排序完成, 1,2,3三个最小的元素移到了列的头部

 

第四轮排序:经过五次比较,第四排序成后,1,2,3,4四个小的素移到了列的部。

完整的排序过程需要经过八轮比(9个元),后四的排过程前面似,过八排序,排过程成。 一个n个数的数列需要排序n-1轮。这样以确得到个有的数。因冒泡序的间复度是O(n2)

冒泡排序代码

在写冒泡排序的代码前,先编写一程序创建序数,用测试序算。 创建无序数列的程randomList.py,代码如下: 

冒泡排序的程bubbleSort.py的代码如下:

 

测试冒泡排序方法,代码如下:

 选择排序

与冒泡排序相比选择排序算法(Selection Sort的原理更加简单粗,就在数中不地找小()的个数。

选择排序算法的基本原理:从数列选择大(小)那个,将个数到合的位,然在删这个的子

中选择最大(最小)的那个数,将个数到合的位……直到子列为

 

以数[6, 1, 7, 8, 9, 3, 5, 4, 2]为例,最初的数列顺序如上图所示

第一轮排序:以数列中第1个数基数遍历列中他的字,到最的那数,后交这两个数(61)置。

第二轮排序:以数列中第2个数基数遍历列中他的字,到最的那个数(2)后交这两(62)置。

第三轮排序:按照上面的规律,不地找余数中最的数,交位置直到原始列排有序列。

选择排序数列完毕。9个数,8轮,间复O(n2)

选择排序的程selectionSort.py码如

 测试选择排序方法,代码如下:

选择排序原理:

①不断将数列中的最小值交换到数列头部实现排序

选择排序的时间复杂度是O(n2)

插入排序

插入排序Insertion Sort很容易理解,插排序法与扑克牌的序很似。打扑时,抓一新牌,

都会与手上已有的牌进行比较,将牌插到比己小牌后。在完所的牌,手已有牌就个有的序

插入排序原理:首先将数列分成两分。列的一个数为left他的right部分。然后right数逐一出,

插入left部分中合适的位置。当right部分为空时,left部分就成为一个序数列

以数[5, 3, 4, 7, 2, 8, 6, 9, 1]为例,最初的数列顺序如上图所示

第一轮排序:先将数列分成左、右部分左半是第个数,右部是列剩的部

第二轮排序:从右半部取出第一个3,与半部5355

 第三轮排序:从右半部取出第一个元4,与半部35,插到合的位上。

N轮排序:从右半部不断取出元,与半部数字较插到左部合的位上,到所数字成排

 插入排序的程insertionsort.py的代码如下:

插入排序的时间复杂度O(n2)

测试插入排序方法,代码如下:

 插入排序原理:

将数列分成两部分,数列的第一个数为left部分,其他的数为right部分

right部分中的数逐一取出,插入left部分中合适 的位置

归并排序

归并排序Merge Sort是一种典型的递归排序它把杂的序过分解一个单的并子列的程。

归并排序原理先将数列分成左右份(好是分),然后左、子数排序毕后合并一起成了个有数列

左、右两个子数列变成有序数列的程是个递过程再把数列成左右两,把子数排序毕后并成

 

 以数[6, 4, 3, 7, 5, 1, 2]为例,最初的数列顺序如上图所示

第一次分组:先将数列分成左、右部分此时4个元3素,不是序数,不合并。

第二次分组:继续分解子数列,分后子序列还有2列,法确长度2数列否有,还继续

第一次合并:经过三次分组,所有子子数列为长1的数。开合并将两有序数列并成个新有序列。

第二次合并:4个子子数列合成两子数,合后两子数均为序数

第三次合并:将剩余的数列合并到个数中。并排完毕3并,终得了一有序列。 归并排序的时间复杂度是O(nLogn)

 

测试插入排序方法,代码如下:

 归并排序原理:

将数列不断分成两组直到不能再分,在合并时排序

归并排序的时间复杂度是O(nlogn)

快速排序

快速排序Insertion Sort也是一种递归排算法。

快速排序原理先以列表中的任意个数基准一般头或),列表为左右两子列

左子列表的数要比基准数小,右子表的要比准数。然继续左子表和子列按同的方继续解、

比较,直到分无可分。最后将左子表(基准小)++右子表(基准大)接起得到个有数列。

以数[3, 5, 8, 1, 2, 9, 4, 7, 6]为例,最初的数列顺序如上图所示

第一次分组:以最后一个元素6基准数列成两分别从左右两端遍历数列,比6的分左边6大的在右。 先从左向右遍历, 当遇到比6大的元素时将该元素到右。同从右左遍时,6元素到左

当全部元素被遍历之后,将左边数,元6,右边列按序拼成新数组此时6的位固定。

递归处理左边子数列:以最后一个2为基2分在边子列中2大的在右子数中 经过一轮分组后,元2的位置经固,接来继递归调用述过……

 

递归处理右边子数列:以最后一个9为基9分在边子列中9大的在右子数中 经过一轮分组后,只会分成一组87再次归处87至此序完毕

 

快速排序的程quicksort.py的代码如下:

 

测试快速排序方法,代码如下:

 快速排序原理:

①不断将数列中的最小值交换到数列头部实现排序

快速排序的时间复杂度是O(n2)

计数排序

计数排序(Counting Sort是一种稳定的线性间排算法该算1954 Harold H. Seward 提出。

计数排序使用一个额外的数组C ,其中第i个元素是待排序数组A中值等于i的元素的数。 然后根据数C 来将A中的元素排到正确的位置

算法的步骤如下:

找出待排序的数组中最大和最小的元, 创建从min, max的连续数组, 并赋初始值为0

统计数组中每个值i的元素出现的次数,存C 的第i

 

  对所有的计数累加(从C 中的第一个元素开始,每一项和前项相

 

反向填充目标数组:将每个元素i放在新数组C[i]项,每放一个素就将C[i]减去1以第一个元素4 为例, 4-1 = 3 在下面的计数数组中找到下标3对应数据6, 在新数组的6-1=5 的位置上填充4

 

 计数排序代码

时间复杂度: O(n+k)

计数排序原理:

找出待排序的数组中最大和最小的元素

统计数组中每个值为i的元素出现次数,存入数组C  的第i项

对所有的计数累加(从C中的第一个元素开始,每 一项和前一项相加)

④反向填充目标数组:将每个元素ii放在新数组的第C[i]项,每放一个元素就将C[i]减去1

堆排序 

堆排序Heap Sort是利堆数据结构进行序的

堆排序原理首先利用待排序数列建最堆(节点存最值,节点数据>子节数据接下来取出堆结构中的根节点元素即为大值保存新列的末

更新剩下的数据, 组成新的最大堆,并取出根节点元(最值),如此断重直到中的有数都被出,序完成

以数[5, 2, 7, 3, 6, 1, 4]为例,最初的数列顺序如上图所示

构建最大堆:最大堆属于二叉堆的种,结点元素是大或等任何个子点的素;最大中任子堆满足 父结点的元素总是大于或等于任何个子点的素这性质。

数列中所有的元素已经存储到最大中。

从最大堆中取出根节点元素:根节元素堆中最大,每出一元素便重新整堆结构保证节点元素剩 下元素中的最大值。这样依次将所元素出,完成序。

 

堆排序的程heapsort.py的代码如

 

 堆排序原理:

①构建最大二叉堆,不断从堆顶取出元素,完成排序

堆排序的时间复杂度是O(nlogn)

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值