算法入门——Python实现十大经典内部排序算法

实践冒泡、选择、插入、希尔、归并、快速、堆、计数、桶、基数排序算法。这些排序算法网上用c++或者java的比较多,我参考网上的例子和代码拿python练练手,不使用python自带函数。

概念

分类
经典的排序算法根据是否需要比较前后两个元素的大小,可分为两类,比较类和非比较类。

稳定性
若a=b,a排在b前面
如果排序之后a仍在b前面,则称算法稳定;
如果排序之后a在b后面,则称算法不稳定。

复杂度
时间复杂度:对数据进行排序所需操作的次数;
空间复杂度:算法执行时占用的计算机内存。

在这里插入图片描述
其中冒泡排序、选择排序、插入排序为基本排序算法。希尔排序、快速排序、堆排序为高效排序算法。归并排序、计数排序、基数排序为牺牲空间节约时间的排序算法。

生成随机数列

import random
import numpy as np
def random_int_list(start, stop, length):
    start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
    length = int(abs(length)) if length else 0
    random_list = []
    for i in range(length):
        random_list.append(random.randint(start, stop))
    return random_list
    
#在1到100之间随机生成10个整数
x=np.array(random_int_list(1,100,10))
print(x)

冒泡排序(Bubble Sort)

算法描述
一次比较两个元素,如果前面的比后面的大,就把两个元素进行调换,相等不调换。依次对从开头到结尾的每一对相邻元素进行比较,为一次循环。重复循环直至排序完成。因为排序过程中,数值大的元素不断后退,数值较小的元素从后面浮上来,称为冒泡排序。在这里插入图片描述
代码实现

#Bubble sort
for i in range(0,len(x)-1):
    for j in range(0,len(x)-1):#一次循环
        if x[j]>x[j+1]:#相邻元素比较
           temp=x[j]#元素交换
           x[j]=x[j+1]
           x[j+1]=temp
print(x)

快速排序(Quick Sort)

算法描述
快速排序采用分治法把一个序列拆分成一个较大和一个较小两个子序列,然后递归的进行排序。
首先选出一个基准数,比基准小的放基准前面,比基准大的放基准后面,这样操作一次后,基准数位于数列中间。再对基准前面的序列和基准后面的序列进行排序。
在这里插入图片描述
代码实现

#Quick sort
def partition(arr,left,right):
    pivot=left
    Index=pivot+1
    for i in range(Index,right):
        if arr[i]<arr[pivot]:
            Index+=1
            swap(arr,i,Index)

    swap(arr,pivot,Index-1)
    return (Index-1)

def swap(arr, i, j):
    temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp
def partition(arr,left,right):
    i=left-1
    pivot=arr[right]
    for j in range(left,right):
        if arr[j]<=pivot:
            i+=1
            arr[i],arr[j]=arr[j],arr[i]
    arr[i+1],arr[right]=arr[right],arr[i+1]
    return(i+1)

def Quicksort(arr,left,right):
    if left<right:
        j=partition(arr,left,right)
        Quicksort(arr, left, j-1)
        Quicksort(arr, j+1, right)

if __name__=="__main__":
    n=len(x)-1
    Quicksort(x, 0, n)
    print(x)

插入排序(Insertion Sort)

算法描述
从第二个元素开始(第一个认为已排序),取出该元素依次与前面的元素进行比较,如果前面的元素大于该元素,则前面的元素后移一位,直到找到小于或等于该元素的位置并将该元素插入位置。
在这里插入图片描述
代码实现

#Insertion sort
for i in range(1,len(x)):
    Index=i
    for j in range(0,i):
        if x[Index]<x[j]:
            temp = x[j]
            x[j]=x[Index]
            x[Index]=temp
print(x)

希尔排序(Shell Sort)

算法描述

插入排序改进版,优先插入距离远的元素。
在这里插入图片描述
代码实现

#Shell sort
for gap in range(len(x)//2,0,-1):
    for i in range(gap,len(x)):
        j=i
        current=x[i]
        if current<x[j-gap]:
            x[j] = x[j - gap]
            j = j - gap
        x[j]=current
print(x)

选择排序(Selection Sort)

算法描述
和冒泡排序相反,选择排序是找最小的元素,放到最前面,在剩下的序列中再找最小的元素放序列首位。
在这里插入图片描述
代码实现

#Selection sort
for i in range(0,len(x)):
    minIndex=i
    for j in range(i+1,len(x)):
        if x[j]<x[minIndex]:
            minIndex=j
    temp = x[i]
    x[i]=x[minIndex]
    x[minIndex]=temp
print(x)

堆排序(Heap Sort)

算法描述
近似二叉树的结构,依据是子节点的元素值总是小于父节点的值。
在这里插入图片描述
代码实现

def heapify(arr,n,i):
    largest=i
    l=2*i+1
    r=2*i+2
    if l<n and arr[i]<arr[l]:
        largest=l

    if r<n and arr[largest]<arr[r]:
        largest=r

    if largest!=i:
        arr[i],arr[largest]=arr[largest], arr[i]
        heapify(arr,n,largest)

def Heapsort(arr):
    n=len(arr)
    for i in range(n,-1,-1):
        heapify(arr, n, i)

    for i in range(n-1,0,-1):
        arr[i],arr[0]=arr[0],arr[i]
        heapify(arr, i, 0)

Heapsort(x)
print(x)

归并排序(Merge Sort)

算法描述
也是采用分治法,将长为n的序列分成两个长为n/2的子序列,对子序列进行归并排序,再把排序好的子序列合成一起。在这里插入图片描述
代码实现

#Merge sort
def depart(lists): #depaart array into one number
    if len(lists) < 2:
        return lists
    middle = len(lists) // 2
    left = depart(lists[:middle])
    right = depart(lists[middle:])
    return merge(left,right)

def merge(a,b):
    result=[]
    i=j=0
    while(i<len(a) and j<len(b)):#左右数组均有值时
        if a[i]<b[j]:
            result.append(a[i])
            i += 1
        else:
            result.append(b[j])
            j += 1

    if i==len(a):#某个数组没值了,把剩余数组的剩余值依次append到新数组中
        for h in b[j:]:
            result.append(h)
    else:
        for h in a[i:]:
            result.append(h)

    return result

if __name__=="__main__":
    print(depart(x))

计数排序(Counting Sort)

算法描述
非比较类排序,将输入的数据值转化为键存储在额外开辟的数组空间中。为一种线性时间复杂度的排序。
在这里插入图片描述
代码实现

#Counting Sort
def Counting_sort(x):
    max_x = max(x)
    Counting = [0] * (max_x + 1)

    for i in x:
        Counting[i] += 1

    sort_x=[]
    for j in range(len(Counting)):
        if Counting[j]!=0:
            for k in range(Counting[j]):
                sort_x.append(j)
    return sort_x

print(Counting_sort(x))

桶排序(Bucket Sort)

算法描述
计数排序升级版,设置一个数组作为空桶,把数据一个个放到对应桶里,满足均匀分布。在这里插入图片描述
代码实现

#Bucket Sort junyunfenbu
def bucket_sort(array):
    minValue=array[0]
    maxValue=array[1]
    for i in array:
        if i<minValue:
            minValue = i
        elif i> maxValue:
            maxValue = i
    bucketcount=(maxValue-minValue+1)

    max_array = max(array)
    bucket = [0] * (max_array + 1)

    for i in array:
        bucket[i] += 1

    sort_array=[]
    for j in range(len(bucket)):
        if bucket[j]!=0:
            for k in range(bucket[j]):
                sort_array.append(j)
    return sort_array

print(bucket_sort(x))

基数排序(Radix Sort)

算法描述
先按照低位,再按照高位排序。
在这里插入图片描述
代码实现

#Radix Sort
def radix_sort(array):
    n=len(array)
    for i in range(2):
        nlist=[[] for j in range(n)] #create new blank list

        for j in array:
            nlist[j//(10**i)%10].append(j)
        array=[a for b in nlist for a in b]

    return array

print(radix_sort(x))

Refence

https://www.cnblogs.com/onepixel/articles/7674659.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值