五大排序算法

一、插入排序

插入排序:每次将一个待排序记录按关键字大小插入到前面已排好的序列中。
如图所示在这里插入图片描述
意味着待排元素前面已经部分有序,所以先和前一个元素相比,1、若待排元素比前面的大则位置不变,2、若比前面元素小,则先用一个哨兵将此待排元素记录下来,前面比哨兵大的数都依次往后挪,直到碰到比哨兵小的数,将此位置的值替换为哨兵。

def InsertSort(a):
    for i in range(2,len(a)):          ## 数组位置从1开始
        if(a[i]<a[i-1]):               ## 当前位置元素于前一个相比(前面已有序)
            temp = a[i]               ## 暂存数组
            for j in range(i-1,0,-1):
                if(temp < a[j]):     
                    a[j+1]=a[j]     ## 依次往后挪(注意!不是交换!插入排序的一大特点就是往后挪!)
                    k = j           ## 用k记录下当前位置
            a[k] = temp            
            print(a[1:])

Tip: 插入排序的一大特点就是往后挪!而不是交换!!!!!!!

a = [0,7,2,24,26,11,5,1,6]   ## 前面那个0没有数值含义,只是为了让数组从1开始
InsertSort(a)

输出:

[2, 7, 24, 26, 11, 5, 1, 6]
[2, 7, 11, 24, 26, 5, 1, 6]
[2, 5, 7, 11, 24, 26, 1, 6]
[1, 2, 5, 7, 11, 24, 26, 6]
[1, 2, 5, 6, 7, 11, 24, 26]

符合插入排序特点。

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

二、希尔排序

希尔排序:先追求部分有序,再逼近全局有序
先将表分成若干子表,对各子表进行直接插入排序,缩小增量d,直到d=1

def ShellSort(a):
    for d in range(int(len(a)/2),0,-1):      ## 从数组长度一半开始划分(小数向下取整)
        for i in range(d+1,len(a)):          ## 从后一个往前判断
            if(a[i]<a[i-d]):                  ## 若逆序,则子表按插入排序
                temp = a[i]                 ## 记录数组(将小的记录下来)
                for j in range(i-d,0,-d):   ## 依次往后挪
                    if(temp<a[j]): 
                        a[j+d] = a[j]
                        k = j
                a[k] = temp
        print(a[1:])
a = [0,7,2,24,26,11,5,1,6]
ShellSort(a)

输出:

[7, 2, 1, 6, 11, 5, 24, 26]
[6, 2, 1, 7, 11, 5, 24, 26]
[1, 2, 6, 5, 11, 7, 24, 26]
[1, 2, 5, 6, 7, 11, 24, 26]

符合希尔排序特点。
(该代码使用for i in range(d+1,len(a)),意为i ++ ,是子表来回切换判断,而不是处理完一个子表再处理下一个)

空间复杂度:O(1)
时间复杂度:最坏O(n^2),当n在某个范围时,O(n ^ 1.3),平均:O(n ^ 1.3)
稳定性:不稳定
适用性:仅用于顺序表

三、冒泡排序

原理:

  1. 从后往前两两比较,若为逆序则交换,最多n-1 趟
  2. 每一趟都使一个元素到最终位置
  3. 若某一趟过程未发生交换,则可提前结束

在这里插入图片描述

def BubbleSort(a):
    for i in range(0,len(a)):
        flag = 0       ## 标记本趟是否发生交换
        for j in range(2,len(a)-i):
            if(a[j]<a[j-1]):      ## 若为逆序,交换
                temp = a[j]       ## 注意当前指针为j,与j-1相比,这样指针j永远指向大的数
                a[j] = a[j-1]
                a[j-1] = temp
                flag = 1      ## 本趟发生交换
        if(flag==0):         ## 本趟未发生交换,提前结束
            break
        print(a)

python中交换两个数的位置还有一种方法:
在这里插入图片描述
so,交换部分可以改成:

def BubbleSort(a):
    for i in range(0,len(a)):
        flag = 0
        for j in range(2,len(a)-i):
            if(a[j]<a[j-1]):
                a[j],a[j-1] = a[j-1],a[j]
                flag = 1
        if(flag==0):
            break
        print(a)

运行:

a = [0,7,2,24,26,11,5,1,6]
BubbleSort(a)
[0, 2, 7, 24, 11, 5, 1, 6, 26]
[0, 2, 7, 11, 5, 1, 6, 24, 26]
[0, 2, 7, 5, 1, 6, 11, 24, 26]
[0, 2, 5, 1, 6, 7, 11, 24, 26]
[0, 2, 1, 5, 6, 7, 11, 24, 26]
[0, 1, 2, 5, 6, 7, 11, 24, 26]

符合冒泡排序特点。
空间复杂度:O(1)
时间复杂度:O(n^2)
稳定性:稳定
适用:顺序表,链表

四、快速排序

任取一个元素作为枢轴,更小元素 < 枢轴 < 更大元素(划分为两部分)

def QuickSort(a, low, high):
    if(low < high):                     ## 递归跳出条件
        s = Partition(a, low, high)     ## 一次划分
        QuickSort(a, low, s-1)          ## 左子表划分
        QuickSort(a, s+1, high)          ## 右子表划分
def Partition(a, low, high):   ## 划分函数
    k = a[high]                ## 将枢轴暂存
    while(low<high):          
        while(a[low]<k and low<high):
            low = low+1
        a[high] = a[low]
        while(a[high]>k and low<high):
            high = high-1
        a[low] = a[high]
    a[low] = k
    print(a[1:])
    return low

调用:

a = [0,7,2,24,26,11,5,1,6,12]
QuickSort(a,0,len(a)-1)
[7, 2, 6, 1, 11, 5, 12, 26, 24]
[1, 2, 5, 6, 11, 7, 12, 26, 24]
[1, 2, 5, 6, 11, 7, 12, 26, 24]
[1, 2, 5, 6, 11, 7, 12, 26, 24]
[1, 2, 5, 6, 7, 11, 12, 26, 24]
[1, 2, 5, 6, 7, 11, 12, 24, 26]

满足快速排序特点。
空间复杂度:O(递归层数){最好:O(log2n),最坏:O(n)}
时间复杂度:O(n递归层数){最好:O(nlog2n),最坏:O(n^n)}
稳定性:不稳定

五、选择排序

原理:每一趟在列表中选取关键字最小的元素加入有序子序列,总共进行 n - 1 趟处理。
在这里插入图片描述

def SelectSort(a):
    for i in range(1,len(a)):    ## n-1趟
        flag = 0                 ## 标记是否有比当前更小的数
        k = i                   ## 记录最小元素位置
        for j in range(i+1,len(a)):
            if(a[j]<a[k]):     ## 比当前最小还小,记录位置
                k = j
                flag=1
        if(flag ==1):        ## flag==1,交换
            a[i],a[k] = a[k],a[i]
        print(a[1:])

运行:

a = [0,7,2,24,26,11,5,1,6]
SelectSort(a)

输出:

[1, 2, 24, 26, 11, 5, 7, 6]
[1, 2, 24, 26, 11, 5, 7, 6]
[1, 2, 5, 26, 11, 24, 7, 6]
[1, 2, 5, 6, 11, 24, 7, 26]
[1, 2, 5, 6, 7, 24, 11, 26]
[1, 2, 5, 6, 7, 11, 24, 26]
[1, 2, 5, 6, 7, 11, 24, 26]
[1, 2, 5, 6, 7, 11, 24, 26]

符合选择排序的特点。
空间复杂度:O(1)
时间复杂度:O(n^2)
稳定性:不稳定
适用性:顺序表、链表

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值