几种排序的实现

 基本排序方法如下

(1)冒泡排序

冒泡排序基本的思路就是2层循环,每次比较相邻2个数,每次把大的数往后移,一层循环下来就能确定一个,这里做了一点优化,内存循环的范围不用一直到底,只要到上一次循环之前就行

def bubblesort(l):
    for x in range(len(l)):
        for y in range(len(l)-x-1):
            if l[y]>l[y+1]:
                k=l[y]
                l[y]=l[y+1]
                l[y+1]=k

(2)选择排序

把一个序列分成2部分,左边视为有序,每次从右边选出一个最小的,放到左边,每次可以确认一个最小的

def selectsort(l):
    for x in range(len(l)):
        min=x
        for y in range(x,len(l)):
            if l[y]<l[min]:
                min=y

        if min!=x:
            k=l[x]
            l[x]=l[min]
            l[min]=k
                

(3)插入排序

插入排序同样是把序列分成左右2部分,每次把右边序列的第一个拿去和左边序列从尾到头进行比较,

def insertsort(l):
    for x in range(1,len(l)):
        k=l[x]
        y=x-1
        while y>=0 and l[y]>k:
            l[y+1]=l[y]
            y=y-1

        l[y+1]=k

(4)堆排序

首先要建立一个大根堆,堆的性质是父节点的值大于左右孩子的值,左右孩子之间没有限制,建立完大根堆后,每次把堆顶元素也就是最大的元素取出来放在数组后面,然后维护这个堆,之后再重复操作,堆取完数组也就出来了

堆排序比较复杂,我们分几个步骤来实现

首先是维护堆,这个方法需要比较父节点和左右孩子节点,找出最大的,如果不是父节点,则要把最大值赋给父节点,并往下继续维护(之一这里比父节点小的节点我们不用去往下维护,这个涉及到我们在建堆时的处理顺序,我们维护的是从由下至上的第一个非叶子节点开始的)

def heapify(l,i,size):
    lchild=2*i+1
    rchild=2*i+2
    max=i
    if lchild < size-1 and l[max]<l[lchild]:
        max=lchild

    if rchild < size-1 and l[max]<l[rchild]:
        max=rchild

    if max!=i:
        k=l[max]
        l[max]=l[i]
        l[i]=k
        heapify(l,max,size)

然后是建堆,叶子结点无法维护,所以我们按倒叙来从第1个非叶子结点来建堆

def buildheap(l):
    for x in reversed(range(0,len(l)/2)):
        heapify(l,x,len(l))

准备工作完成了就可以实现堆排序了,在排序内部我们要不断取堆顶并维护新的堆

def heapsort(l):
    heapsize=len(l)
    buildheap(l)
    while heapsize>1:
        heapsize=heapsize-1
        k=l[0]
        l[0]=l[heapsize]
        l[heapsize]=k
        heapify(l,0,heapsize)

下面是完整代码

def heapify(l,i,size):
    lchild=2*i+1
    rchild=2*i+2
    max=i
    if lchild<size and l[max]<l[lchild]:
        max=lchild

    if rchild<size and l[max]<l[rchild]:
        max=rchild

    if max!=i:
        k=l[max]
        l[max]=l[i]
        l[i]=k
        heapify(l,max,szie)


def buildheap(l,n):
    heapsize=n
    for x in reversed(range(0,n/2-1)):
        heapify(l,x,heapify)

    return heapsize


def heapsort(l):
    n=len(l)
    heapsize=buildheap(l,n)
    while heapsize>1:
        heapsize=heapsize-1
        k=l[0]
        l[0]=l[heapsize]
        l[heapsize]=k
        heapify(l,0,heapsize)

(5)归并排序

也叫二分排序,简单来说就是把一个序列分成2部分,再继续递归下去直到每个序列只有1个数,然后开始两两合并

def merge(l, left, right,mid):
    res = []
    x = left
    y = mid + 1
    while x <= mid and y <= right:
        if l[x] <= l[y]:
            res.append(l[x])
            x = x + 1
        else:
            res.append(l[y])
            y = y + 1
    while x <= mid:
        res.append(l[x])
        x = x + 1

    while y <= right:
        res.qppend(l[y])
        y = y + 1
    for i in range(0, len(res)):
        l[left + i] = res[i]


def mergesort(l, left, right):
    if left==right:
        return
    mid = (left + right) / 2
    mergesort(l, left, mid)
    mergesort(l, mid + 1, right)
    merge(l, left, right,mid)

(6)快速排序

快排的思路和二分有点像,不过快排是每次把序列份左右2部分,选一个基准元素,比它大的放右边,小的放左边,这个靠两边递进的循环来实现

def part(l,left,right):
    pivo=l[left]

    while left<right:
        while left<right and l[right]>=pivo:
            right=right-1

        k=l[right]
        l[right]=l[left]
        l[left]=k

        while left<right and l[left]<=pivo:
            left=left+1

        k=l[right]
        l[right]=l[left]
        l[left]=k
    return left

def quicksort(l,left,right):
    if left<right:
        pivo=part(l,left,right)

        quicksort(l,left,pivo-1)
        quicksort(l,pivo+1,right)

猜你喜欢

转载自blog.csdn.net/wzngzaixiaomantou/article/details/81436964
今日推荐