排序:选择、插入、冒泡、归并、快排、堆排序的Python实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ZZh1301051836/article/details/89027642

1 复杂度分析

空间复杂度都是O(1)的:
选择排序:最好、最坏、平均都是O(n2)。
插入排序:最好O(n),最坏O(n2),平均O(n2)。
冒泡排序:不稳定,最好O(n)、最坏O(n2)、平均都是O(n2)。
归并排序:最好、最坏、平均都是O(nlogn)。
堆排序:最坏O(nlogn)。

空间复杂度为O(nlogn):
快速排序:最坏O(n2),最好O(nlogn),平均O(nlogn)。

2 程序实现

# 选择排序:找出序列中最小的数,与第一个数交换。记录的是下标
def select_sort(lists):
    count = len(lists)
    for i in range(0,count):
        min = i
        for j in range(i+1,count):
            if lists[j] < lists[min]:
                min = j
        lists[i],lists[min] = lists[min],lists[i]
    return lists
#--------------------------------------------------------------
#插入排序 :第一个元素为一个序列,后面的元素插入到前面的序列中
def insert_sort(lists):
    count = len(lists)
    for i in range(1,count):
        key = lists[i]
        j = i-1
        while j>=0:
             if lists[j] >= key:
                 lists[j+1] = lists[j]
                 lists[j] = key
             j-=1
    return lists
#--------------------------------------------------------------
#冒泡排序:第一个元素与后面的元素比较,大的往上冒
def bubble_sort(lists):
    count = len(lists)
    for i in range(0,count-1):#不遍历最后一个元素,比较大小的时候,就用到最后一个元素了
        for j in range(0,count-1-i):#第一次是[0,倒数第二个元素] ,后面end逐渐减1
            if lists[j]>lists[j+1]:
                lists[j], lists[j + 1] = lists[j+1], lists[j]
    return lists

#--------------------------------------------------------------
def merge(left,right):
    result = []
    i , j = 0, 0
    while i <= len(left) and right <= len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.append(left[i:])
    result.append(right[j:])

    return right


#归并排序:相邻元素合并,递归与分治
def merge_sort(lists):
    if len(lists)<=1:
        return lists

    num = len(lists)/2
    left = merge_sort(lists[:num])
    right = merge_sort(lists[num:])

    return merge(left,right)

#--------------------------------------------------------------
def partition(lists,low,high):#交换字表l[low:high]中的元素,使枢轴到位
    key = lists[low] #初始关键字是第一个元素
    while low<high:
        while low<high and lists[high]>key: high -= 1;
        lists[low] = lists[high]

        if low<high and lists[low]<key: low += 1
        lists[high] = lists[low]

    lists[low] = key #此时,low==high
    return low #返回枢轴

#快速排序:两边往中间走,分解成两部分,左边都小于右边
def quick_sort(lists,low,high):
     if low<high:
         pivotloc = partition(lists,low,high) #获取枢轴位置
         quick_sort(lists,low,pivotloc-1)
         quick_sort(lists,pivotloc+1,high)
#--------------------------------------------------------------
def adjust_heap(lists,i,size):
    lchild = 2*i+1
    rchild = 2*i+2

    import math
    min = i #建立个小顶堆
    if i<size/2: #因为下标是从0开始的,所以不取等号,后面的左右孩子结点与size比较,也是同样的道理
        if lchild<size and lists[lchild]<lists[min]:
            min = lchild
        if rchild<size and lists[rchild]<lists[min]:
            min = rchild
        if min != i:
            lists[i],lists[min] = lists[min],lists[i]
            adjust_heap(lists,min,size)

def build_heap(lists,size): #从第一个非终端结点开始调整
    import math
    for i in range(0,math.floor(size/2))[::-1]:#[0...n/2]这是所有的非终端结点,倒序遍历(即从n/2)开始遍历
        adjust_heap(lists,i,size)

def heap_sort(lists):
    size = len(lists)
    build_heap(lists,size) #建堆
    for i in range(0,size)[::-1]:
        lists[0],lists[i] = lists[i],lists[0] #当前最小的是lists[0],将最小的与最后一个交换,最后得到的lists就是一个倒序序列
        adjust_heap(lists,0,i) #调整 lists[i,i+1...]都已经拍好序了,不看这些,将剩下的看做一棵待调整的完全二叉树

#--------------------------------------------------------------
if __name__=='__main__':
    lists = [3,4,2,8,9,5,1]

    # select_sort(lists) #选择排序
    # insert_sort(lists) #插入排序
    # bubble_sort(lists) #冒泡排序
    # merge_sort(lists) #归并排序
    #quick_sort(lists,0,len(lists)-1)
    heap_sort(lists)
    for i in lists:
        print(i)

猜你喜欢

转载自blog.csdn.net/ZZh1301051836/article/details/89027642
今日推荐