python实现简单排序算法

冒泡排序:

比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

时间复杂度:O(n^2)
最优时间复杂度:O(n)
稳定性:稳定

def bubble(li):
    n = len(li)
    # j 代表 当前无序序列的个数
    for j in range(n,1,-1):
        # 1 将序列最大数移动到无序序列尾端(遍历比较,前大后小则交换)
        count = 0
        for i in range(0,j-1):
            if li[i]>li[i+1]:
                li[i],li[i+1] = li[i+1],li[i]
                count += 1
        # 若没有发生交换,则算法退出
        if count==0:
            return
    # 2 对剩余无序序列li[0:n-1]重复步骤1

选择排序:

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

时间复杂度:O(n^2)   
稳定性:不稳定

def selection(li):
    n = len(li)
    # j 代表当前有序序列的个数(无序序列的首个元素位置)
    for j in range(0,n-1):
        # 1 找到最小元素并记录该值索引(遍历比较,小则更新)
        index = j
        for i in range(j+1,n):
            if li[i]<li[index]:
                index = i
        # 至此,第min_index个元素就是最小元素
        # 2 交换最小值和无序序列首个元素
        li[index],li[j] = li[j],li[index]
     # 3 对剩余无序序列li[1:n]重复步骤1 2

插入排序:

通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

时间复杂度:O(n^2)
最优时间复杂度:O(n)
稳定性:稳定

def insertion(li):
    n = len(li)
    #j 代表当前有序序列的个数
    for j in range(1,n):
        # 1 将无序序列首个元素向前插入有序序列(反向遍历,前大后小则交换)
        for i in range(j,0,-1):
            if li[i]<li[i-1]:
                li[i],li[i-1] = li[i-1],li[i]
            else:
                # 若没有发生前大后小则步骤1结束
                break
      # 2 对剩余无序序列重复步骤1

希尔排序:

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

平均时间复杂度O(n^1.3~2)
最优时间复杂度:O(nlogn)
最坏时间复杂度:O(n^2)

def shell(li):
    n = len(li)
    # 1 确定步长分组(步长=长度的一半)
    mid_ = n//2
    while mid_ > 0 :
        # 2 组内插入排序
        for j in range(mid_,n):
            for i in range(j,0,-mid_):
                if li[i-mid_]>li[i]:
                    li[i],li[i-mid_] = li[i-mid_],li[i]
                else:
                    break
        # 3 缩小步长一半,重复步骤2
        mid_ = mid_//2

快速排序:

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

最优时间复杂度:O(nlogn)
最坏时间复杂度:O(n^2)
 稳定性:不稳定

def quick(li,start,end):
    if start>=end:
        return
    head = start
    tail = end
    # 1 确定基准值已经基准索引(中间位置)
    index = (start+end)//2
    while head<tail:
        # 2 在基准值前找比基准值大的元素(向后遍历),交换并更新基准索引
        while li[head]<=li[index] and head < index:
            head +=1
        li[head],li[index] = li[index],li[head]
        index = head
         # 3 在基准值后找比基准值小的元素(向前遍历),交换并更新基准索引
        while li [tail]>=li[index] and tail>index:
            tail-=1
        li[tail],li[index] = li[index],li[tail]
        index = tail
        # 4 重复步骤2 3 直到首尾重合
    # 至此,原序列被分成li[start:pivot_index]和li[pivot_index+1:end+1]
    # 5 对前后序列重复步骤1 2 3 4
    quick(li,start,index-1)
    quick(li,index+1,end)

归并排序:

将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。

时间复杂度:O(nlogn)
稳定性:稳定

def merge_sort(li):
    n = len(li)
    while n <= 1:
        return
    left = li[:n//2]
    right = li[n//2:]
    merge_sort(left)
    merge_sort(right)

    # 1递归分解,分到不能分为止
    li[:] = []
    l_index = 0
    r_index = 0
    # 2返回合并,合并两个有序序列(同时遍历,选择小的放到新序列li)
    while l_index<len(left) and r_index<len(right):
        if left[l_index] <= right[r_index]:
            li.append(left[l_index])
            l_index+=1
        else:
            li.append(right[r_index])
            r_index+=1


    # 至此,某个序列遍历完了,将另一个序列的后续元素追加到li后
    li+=left[l_index:]
    li+=right[r_index:]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值