列表之堆排序

二叉树

树节点:类似于目录结构。

二叉树:度不超过2的树,即节点最多有两个叉。

满二叉树:每一层填满,每个节点都有两个叉;

完全二叉树:就是从满二叉树抽走几个分支,但是所有节点要么没有分支,要么就要连两个分支;

非完全二叉树:但凡有一个节点只有一个分支。


二叉树存储方式

链式存储方式:以树结构方式存储;

顺序存储方式:以列表方式存储;

大根堆:一颗完全二叉树,满足任意节点都比其子节点大:

小根堆:一颗完全二叉树,满足任意节点都比其子节点小:

堆排序过程

1、建立堆;

2、得到堆顶元素为最大元素;

3、去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序;

4、堆顶元素为第二大元素;

5、重复步骤3,直到堆变空。

堆调整

构建函数:

def adjust(lst, left, right):
    """
    一次堆调整
    :param lst:传入的列表
    :param left: 初始值0
    :param right: len(lst)-1
    :return:
    """
    i = left  # 初始值
    j = 2 * i + 1  # 子元素左侧值
    temp = lst[left]  # 保存堆顶值

    # 比较堆顶和其子元素大小
    while j <= right:
        if j + 1 <= right and lst[j] < lst[j + 1]:  # 取出子元素中较大者
            j += 1

        if temp < lst[j]:  # 若temp比子元素较大者小,则将较大者移到父节点
            lst[i] = lst[j]
            i = j
            j = 2 * i + 1
        else:
            break

    lst[i] = temp



lst = [2,9,7,8,5,0,1,6,4,3]

adjust(lst,0, len(lst)-1)

print(lst) # [9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
建堆
def heap_sort(lst):
    """
    构建堆
    :param lst:
    :return:
    """
    n = len(lst)
    #  找所有的父元素节点的位置,最后一个父节点位置为n/2-1

    for i in range(n//2 -1, -1, -1):
        adjust(lst,i,n-1)  # right统一指最后一个数

    print(lst)


data = [6,8,1,9,3,0,7,2,4,5]
heap_sort(data)  # [9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
排序出结果
def heap_sort(lst):
    """
    构建堆
    :param lst:
    :return:
    """
    n = len(lst)
    #  找所有的父元素节点的位置,最后一个父节点位置为n/2-1

    for i in range(n//2 -1, -1, -1):
        adjust(lst,i,n-1)  # right统一指最后一个数
    
    
    for j in range(n-1, -1, -1):  # 挨个出数
        lst[0],lst[j] = lst[j],lst[0]
        adjust(lst,0,j-1)

    # print(lst)


data = list(range(100000))
import random
random.shuffle(data)


@cal_time
def cal_heap_sort(data):
    heap_sort(data)


cal_heap_sort(data)  #cal_heap_sort running time: 1.4254436492919922 secs.
# 10万级别仅需要1.4s

# 同样数据排序:cal_quick_sort running time: 0.8465578556060791 secs.

猜你喜欢

转载自www.cnblogs.com/fqh202/p/9375453.html