python数据结构与算法(冒泡,选择,插入,快速)

近期总结。

一.冒泡排序(Bubble Sort)

冒泡排序,是一种简单的排序算法,实现方式可以简单理解为依次比较两个相邻元素,根据由大到小或者由小到大的规则,进行交换。由冒泡的名称也可联想一二,这种排序方式会使较大或者较小的元素慢慢浮到顶端。
具体运作如下(升序为例)
1.一个序列,从第一位元素开始,比较第一第二位,若第一位值大于第二位(不符合升序规则),将两个元素交换位置;否则继续比较第二和第三位。这样两两比较直到没有相邻元素交换。
2.这样一轮比较下来,可以保证的是最后一位是最大的。所以剔除最后一位,再次重复第一步操作。
3.每一轮后去除最后一位,对越来越少的剩余元素重复上述步骤,直到没有数字进行比较。
冒泡排序动态演示
冒泡效果
python的实现

def maopao(arr):
    # 外循环每次剔除最后一位,逐渐减小,共循环n-1次
    for i in range(len(arr)-1,0,-1):
        # 内循环进行除最后一位的两两比较
        for j in range(i):
            # 不符合升序规则,进行交换
            if arr[j] > arr[j+1]:
                arr[j],arr[j+1] = arr[j+1],arr[j]

时间复杂度
1.最优时间复杂度:O(n) --遍历一次未发现可交换元素
2.最坏时间复杂度:O(n2)
3.稳定性:稳定

二.选择排序(Selection sort)

选择排序,是一种比较直观的排序方法。实现方法可以简单理解为把最大或者最小的元素选出来,通过交换放在前排。个人理解起来感觉和冒泡有点像,选取完后放在前排,然后在剩下的元素里再选取最大或最小接着放在前排,可以结合冒泡冒到顶端的思想,在这方面有点异曲同工。在排序时核心还是交换元素。
具体运作如下最(升序为例):
1.首先假定第一个元素为最小,来遍历之后的元素,如果发现有比第一个元素还小的,那么交换这两个元素。
2.这样排下来,可以保证的是第一个元素为最小元素。接下来剔除第一位,从第二位重复上述操作。
3.每次剔除最前一位,依次循环下来,得出排序。
选择排序动态演示
选择排序
python的实现:

def xuanze(arr):
    # 循环到倒数第二位,即 共循环n-1次
    for i in range(len(arr)-1):
        # 假定最小元素索引为当前开始元素
        min_ind = i
        # 在当前元素之后进行遍历,查找最小元素索引
        for j in range(i+1,len(arr)):
            if arr[j] < arr[min_ind]:
                min_ind = j
         #查找完毕,进行交换
        arr[i],arr[min_ind] = arr[min_ind],arr[i]

时间复杂度
1.最优时间复杂度:O(n2)
2.最坏时间复杂度:O(n2)
3.稳定性:不稳定(考虑升序每次选择最大的情况)

三.插入排序(Insertion Sort)

插入排序,也是比较直观的一种排序方法。从名称上理解,插入,举例来说,当有一个新数据要插入原有序列,假定为从小到大,形成新的有序列表,我们采用从后往前的方法比较,当发现某个元素比新元素大,我们会将该元素往后移一位,这样从后往前依次比较,发现某个元素比新元素小时,停止移位,将新元素插入,最终完成插入。该方法首先要基于有一个有序列表,所以从单一元素开始排起,逐步至排完。
具体运作如下最(升序为例):
1.从首位开始,插入第二位元素,若该元素大于首位元素,则不动;不然交换位置。接着第三个元素,从第二个元素开始比较,若第二个元素大于第三个元素,则移位,再同理同第一个元素相比。
2.这样依次比较,移位,插入,直到比完。
插入排序动态演示
插入排序
python实现

def charu(arr):
    # 外循环共n-1次
    for i in range(1,len(arr)):
        # 内循环,从当前i,从后往前开始移位插入
        for j in range(i,0,-1):
            # 若后位元素小于前位元素,则交换前移
            if arr[j] < arr[j-1]:
                arr[j],arr[j-1] = arr[j-1],arr[j]

时间复杂度
1.最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
2.最坏时间复杂度:O(n2)
3.稳定性:稳定

四.快速排序(Quicksort)

快速排序,相较前三种,感觉有点不一样。引用百度百科释义“通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。”
个人理解,选一个中间数,把比该元素大的分一个列表,比该元素小的分一个列表,引用递归思想,再对分出来的两个列表同理,递归直到分出来的列表只有一个元素。
快速排序图示
快速排序
这个图示,比较清楚的展示了快速排序的过程,也提供了一套实现思路,主要是通过设置左右两个游标,进行易位分区,当初看到动手就觉得有点复杂。后来看过某位大神写的,非常优雅厉害,理解也很畅通。这里分别尝试两套思路实现。

python常规实现

def kuaisu(arr,start,end):
    # 递归退出条件
    if start>=end:
        return
    # 假定中间值
    mid = arr[start]
    # 设置左右游标
    left = start
    right = end
    #游标未重合
    while left < right:
        # 右分区为大区,如果比中间值大,游标移动
        if left < right and arr[right]>=mid:
            right-=1
        # 比中间值小,将该值易位到左游标
        arr[left] =arr[right]
        # 左分区为小区,如果比中间值小,游标移动
        if left <right and arr[left]<mid:
            left+=1
        # 比中间值大,将该值易位到右游标
        arr[right] = arr[left]
    # 此时左右游标重合,将中间值放上
    arr[left] = mid
    # 分别对两边进行递归
    kuaisu(arr,start,left-1)
    kuaisu(arr,left+1,end)

python优雅实现

def quicksort(arr):
    # 递归退出条件,当arr为1时不需要再排序
    if len(arr)<2:
        return arr
    else:
        mid = arr[0]
        # 剩余元素大小分区
        min_l = [i for i in arr[1:] if i <=mid]
        max_l = [i for i in arr[1:] if i >mid]
        # 递归大小分区
        return quicksort(min_l)+[mid]+quicksort(max_l)

时间复杂度
1.最优时间复杂度:O(nlogn)
2.最坏时间复杂度:O(n2)
3.稳定性:不稳定

总的来说,冒泡,选择,插入比较好理解,共同点是通过交换元素的方法,完成某种特定的排序。快速排序说是冒泡排序的一种改进,刚接触,理解还不是那么深刻,感觉还需多磨。
写在最后,这几天研究数据结构和算法,虽然还是有点懵,但是慢慢磨下来,还是感觉不错 ,每天磨一磨,理解也越来越深,果然还是多练!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值