排序算法笔记

**

排序算法(python)

排序算法的时间复杂度

冒泡排序

思想:从第一个数开始,与后面一个数进行两两比较交换,直到最后最大的数被交换到最后一个位置,冒泡排序是一个稳定的排序算法;
时间复杂度:需要从头到尾遍历n的平方次,所以冒泡排序的时间复杂度是
O(n2),但是它的最优的时间复杂度是O(n),当一个数组完全有序时,设置一个flag的指针,当flag为false时,就可以直接返回,不用遍历后面的;
空间复杂度:O(1)
稳定性:稳定
一般的冒泡排序的代码:

def bubble_sort(arr):
    n=len(arr)
    for i in range(0,n-1):
        for j in range(0,n-i-1):
            if arr[j]>arr[j+1]:
                arr[j+1],arr[j]=arr[j],arr[j+1]
    return arr

时间复杂度为O(n)的冒泡排序的代码:

def bubble_sort(arr):
    n=len(arr)
    for i in range(0,n-1):
        flag=False
        for j in range(0,n-i-1):
            if arr[j]>arr[j+1]:
                flag=True
                arr[j+1],arr[j]=arr[j],arr[j+1]
        if flag==False:
            return
    return arr

选择排序

思想:在一堆数中选择最小的一个数放在第一个位置,然后再在剩下的数中选择第二小的数放在第二个位置,这样依次遍历下去
时间复杂度:O(n2),最优的时间复杂度和最优的时间复杂度都是O(n2),不管是有多少个数,都是n个数进行n次比较
空间复杂度:只用到有限的几个变量,所以空间复杂度是O(1)
稳定性:不稳定,因为是第一个数与后面的数进行交换,会改变数之间的相对位置,所以是不稳定
代码:

def select_sort(arr):
    n=len(arr)
    for i in range(0,n-1):
        min_index=i
        for j in range(i,n):
            if arr[j]<arr[min_index]:
                min_index=j
        if min_index!=i:
            arr[i],arr[min_index]=arr[min_index],arr[i]
    return arr

插入排序

思想:从第二个数开始,插入到前面已经排好序的数,要插入的前i个数已经排好序了
时间复杂度:时间复杂度为O(n2),因为要遍历后面的n个数,与前面已经排好序的n个数进行比较,然后选择插入一个位置;最好的时间复杂度是O(n),当数组是完全有序的时候,不用与前面进行比较,所以最好情况下的时间复杂度是O(n)
空间复杂度:O(1)
稳定性:稳定的(可以决定换不换位置)
代码块:

def insert_sort(arr):
    n=len(arr)
    for i in range(1,n):
        pre_index=i-1
        cur=arr[i]
        while pre_index>=0 and arr[pre_index]>cur:
            arr[pre_index+1]=arr[pre_index]
            pre_index-=1
        arr[pre_index+1]=cur
    return arr

归并排序

思想:先左边一个有序排列,再右边一个有序排列,然后再把这两部分合并,利用一个递归结构把列表中的数一分为2,然后再进行合并
时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:稳定的,归并排序是具有稳定性的,在归并的过程中是稳定的
代码:

def merge_sort(arr):
    if len(arr)==1:
        return arr
    n=len(arr)
    mid=n//2
    left=merge_sort(arr[:mid])
    right=merge_sort(arr[mid:])
    merge(left,right)
    return arr
def merge(left,right):
    result=[]
    if left[0]<=right[0]:
        result.append(left[0])
    else:
        result.append(right[0])
    result+=left
    result+right
    return result

快速排序

思想:从一个序列中随机选择一个数作为基准(一般选择最后一个数),然后再遍历这个数组,比这个数小的放在左边,比这个数大的放在右边,然后再进行左右两边序列的递归操作
时间复杂度:遍历一遍序列,时间复杂度是n,然后再对左右两边进行递归操作,所以时间复杂度是logn,所以整个快排总的时间复杂度是O(nlogn)
空间复杂度:只用到了有限的几个变量,所以空间复杂度是O(1)
稳定性:快排有进行数字的交换,所以是不稳定的
代码:

def quick_sort(arr,low,high):
    if low<high:
        p=pat(arr,low,high)
        quick_sort(arr,low,p-1)
        quick_sort(arr,p+1,high)
    return arr
def pat(arr,low,high):
    pivot=arr[high]
    i=low-1
    for j in range(low,high):
        if arr[j]<=pivot:
            i+=1
            arr[i],arr[j]=arr[j],arr[i]
    arr[i+1],pivot=pivot,arr[i+1]
    return i+1

希尔排序

思想:希尔排序也称缩小增量排序,是插入排序的一种优化,将一个序列按照若干个间隔分成若干个子序列,然后再对子序列进行插入排序,这个是在序列基本有序的情况下进行插入排序的,所以希尔排序的效率比直接插入排序要高一些
时间复杂度:希尔排序的时间复杂度的下限为O(nlogn),但是希尔排序没有快排快,因此对中等规模的数据表现良好,但对于规模非常大的数据,希尔排序不是最优的选择
空间复杂度:只用到了有限的几个变量,因此希尔排序的空间复杂度为O(1)
稳定性:有进行数据的交换,所以希尔排序是不稳定的

def shell_sort(arr):
    n=len(arr)
    gap=n//2
    while gap>=1:
        for j in range(gap,n):
            tempindex=j
            while tempindex>=gap and arr[tempindex-gap]>arr[tempindex]:
                arr[tempindex-gap],arr[tempindex]=arr[tempindex],arr[tempindex-gap]
                tempindex-=gap
        gap=gap//2
    return arr

堆排序

思想:先建立一个大顶堆,然后再把第一个数与最后一个数进行交换,再建立一个大顶堆
时间复杂度:建立一个大顶堆的时间复杂度是O(n),调整大顶堆的时间复杂度是O(logn),需要遍历整个序列,所以整个的时间复杂度是O(nlogn)
空间复杂度:只用到了少数的几个变量,所以空间复杂度为O(1)
稳定性:堆排序有进行数的交换,所以堆排序是不稳定的
代码:

def heapify(arr,n,i):
    if i>n:
        return
    c1=2*i+1
    c2=2*i+2
    max_index=i
    if c1<n and arr[c1]>arr[max_index]:
        max_index=c1
    if c2<n and arr[c2]>arr[max_index]:
        max_index=c2
    if max_index!=i:
        arr[max_index],arr[i]=arr[i],arr[max_index]
        heapify(arr,n,max_index)
    return arr
def build_sort(arr):
    n=len(arr)
    last_node=n-1
    parent_node=last_node//2
    for i in range(parent_node,-1,-1):
        heapify(arr,n,i)
    return arr
def heap_sort(arr):
    n=len(arr)
    build_sort(arr)
    for i in range(n-1,-1,-1):
        arr[0],arr[i]=arr[i],arr[0]
        heapify(arr,i,0)
    return arr

桶排序

思想:桶排序是先找出一个最大元素和一个最小元素,假设这两个元素之间的间隔为k,初始化一个有k个元素的桶,将桶里面都初始化为0,然后再遍历这个序列,最终以排序的形式进行输出
时间复杂度:O(n)
空间复杂度:O(n),桶排序是一种以空间换时间的一种排序
稳定性:桶排序算法是一种稳定的算法
代码:

def bucket_sort(arr):
    n=len(arr)
    max_number=max(arr)
    bucket=[0]*(max_number+1)
    for i in arr:
        bucket[i]+=1
    sort_nums=[]
    for j in range(len(bucket)):
        if bucket[j]!=0:
            for y in range(bucket[j]):
                sort_nums.append(j)
    return sort_nums
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值