各种排序方法与其python实现

一.冒泡排序
思路(稳定):
算法时间复杂度:O(n²)
算法空间复杂度:O(1)
第一轮:从第一个数和第二个数开始,将较大的那个放在后面,再到第二个和第三个数,一直到最后一个数。就会把最大的数放在数列的最后。第二轮:从第一个数和第二个数开始,将较大的那个放在后面,再到第二个和第三个数,一直到倒数第个数。就会把第二大的数放在数列的倒数第二位。一直到每个数都排列好。

def maopao_sort(list):
    if not list or len(list) <= 1:
        return
    list_len = len(list)
    for i in range(list_len - 1):
        swap_flag = True
        for j in range(0, list_len - 1 - i):
            if list[j] > list[j + 1]:
                tmp = list[j]
                list[j] = list[j + 1]
                list[j + 1] = tmp
                swap_flag = False
        if swap_flag:
            return list

二.选择排序
思路(不稳定(当列表有重复数会出错)):
稳定(是相对位置稳定,比如552,用选择排序最终结果是第一个5和2位置交换,两个5的相对位置发生改变,所以不稳定)
算法复杂度:O(n²)
算法空间复杂度:O(1)
第一轮:从第一个开始遍历一遍列表,然后和最小的交换位置。第二轮:从第二个数开始遍历列表,然后和最下的交换位置。一直到最后剩下最大的那个。

def xuanze_sort(list):
    if not list or len(list) <= 1:
        return
    list_len = len(list)
    for i in range(list_len - 1):
        j_tmp = i
        min = list[i]
        for j in range(i + 1, list_len):
            if list[j] < min:
                j_tmp = j
                min = list[j]
        if i != j_tmp:
            tmp = list[i]
            list[i] = list[j_tmp]
            list[j_tmp] = tmp
    return list

三.插入排序
算法复杂度:O(n²)
算法空间复杂度:O(1)
算法稳定性:稳定
思想:
第n轮将list的第n+1个数与第n个,第n-1、、、第一个数进行比较,只要小于比较的数就换位置。
在这里插入图片描述

def charu_sort(list):
    if not list or len(list) <= 1:
        return
    list_len = len(list)
    for i in range(1, list_len):
        for j in range(0, i + 1):
            if list[i] < list[j]:
                break
        if j <= i:
            tmp_i = i
            x = list[i]
            while tmp_i > j:
                list[tmp_i] = list[tmp_i - 1]
                list[tmp_i - 1] = x
                tmp_i -= 1
            list[j] = x
    return list

四.快速排序
算法复杂度:O(nlgn)
算法空间复杂度:O(1)
算法稳定性:不稳定(很多交换的)
思想:
将list的第一个数作为比较的点,将数列分为左右两部分,左边小于等于比较点,右边大于等于比较点。再将左右两个list分别重复这样的操作,直到分不下去。
在这里插入图片描述

def kuaisu_sort(list, start=0, end=0):
    if not list or len(list) <= 1 or start > end:
        return
    if start == 0 and end == 0:
        end = len(list) - 1
    start_tmp = start
    end_tmp = end
    x = list[start_tmp]
    while start_tmp < end_tmp:
        while start_tmp < end_tmp and list[end_tmp] >= x:
            end_tmp -= 1
        if start_tmp < end_tmp:
            list[start_tmp] = list[end_tmp]
            start_tmp += 1
        while start_tmp < end_tmp and list[start_tmp] <= x:
            start_tmp += 1
        if start_tmp < end_tmp:
            list[end_tmp] = list[start_tmp]
            end_tmp -= 1
    list[start_tmp] = x
    kuaisu_sort(list, start, start_tmp - 1)
    kuaisu_sort(list, start_tmp + 1, end)
    return list

五.归并排序
算法复杂度:O(nlgn)
算法空间复杂度:O(n)
算法稳定性:稳定
思想:
将list均分成左右两个list,再对每个list均分。分到最小以后对所有小list中的两个数排序,再做list间的排序,先比两个list的第一个数,小的放第一位,再比剩下的那个第一个数,和另一个list的第二个。一直这样排序,直到排序完成。最后将左右两个list进行排序就可以了
在这里插入图片描述
代码`

def merge(a, b):
    c = []
    h = j = 0
    while j < len(a) and h < len(b):
        if a[j] < b[h]:
            c.append(a[j])
            j += 1
        else:
            c.append(b[h])
            h += 1
    if j == len(a):
        for i in b[h:]:
            c.append(i)
    else:
        for i in a[j:]:
            c.append(i)
    return c

def guibin_sort(lists):
    if len(lists) <= 1:
        return lists
    middle = len(lists)//2
    left = guibin_sort(lists[:middle])
    right = guibin_sort(lists[middle:])
    return merge(left, right)

六.堆排序
七.计数排序
算法时间复杂度:O(n+m)
算法空间复杂度:O(m)
算法稳定性:稳定
思想:
计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有17个元素的值小于x的值,则x可以直接存放在输出序列的第18个位置上。
代码:

def jishu_sort(input_list):
    length = len(input_list)
    if length < 2:
        return input_list
    max_num = max(input_list)
    count = [0] * (max_num + 1)
    for element in input_list:
        count[element] += 1
    output_list = []
    for i in range(max_num + 1):
        for j in range(count[i]):  # count[i]表示元素i出现的次数,如果有多次,通过循环重复追加        
            output_list.append(i)
    return output_list
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值