作者:safecaps | 来源:互联网 | 2023-05-17 10:24
本文主要分享【堆排序过程图解】,技术文章【堆排序(heap-sort)】为【fiveym】投稿,如果你遇到数据结构和算法相关问题,本文相关知识或能到你。堆排序过程图解堆排序(heap-sor
本文主要分享【堆排序过程图解】,技术文章【堆排序(heap-sort)】为【fiveym】投稿,如果你遇到数据结构和算法相关问题,本文相关知识或能到你。
堆排序过程图解
堆排序(heap-sort) 堆排序前传--树与二叉树二叉树的基础知识二叉树的存储方式什么是堆堆的向下调整性质堆排序的过程向下调整的函数实现 堆排序的实现堆排序中的topk问题
堆排序前传–树与二叉树 树是一种数据结构 比如:目录结构树是一种可以递归定义的数据结构树是由n个结点组成的集合: 如果n=0,那这是一棵空树如果n>0,那么存在1个结点作为数的根结点,其他结点可以分为m个集合,每个集合本身有事一棵树。
一些概念:
根结点(A),叶子结点(树的末端B,C,H,I,P,Q,K,L,M,N)树的深度(高度),就是最深有几层:4层树的度,就是分出的最多的那个的,A:6度孩子结点/父结点子树:E,I,J,P,Q 二叉树的基础知识 度不超过2的树每个结点最多有两个孩子结点两个孩子结点被区分为左孩子结点和右孩子结点
满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。
完全二叉树:叶结点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。
二叉树的存储方式
二叉树的存储方式(表示方式)
链式存储方式
顺序存储方式
父节点和左孩子结点的编号下标有什么关系?
0-1 1-3 2-5 3-7 4-9父节点为i: i—>2i+1
父节点和右孩子结点的编号下标有什么关系?
0-2 1-4 2-6 3-8 4-10父节点为i:i—>2i+2
什么是堆
堆:一种特殊的完全二叉树结构
大根堆:一棵完全二叉树,满足任一结点都比其孩子结点大小根堆:一棵完全二叉树,满足任一结点都比其孩子节点小
堆的向下调整性质 假设根节点的左右子树都堆,但根结点不满足堆的性质可以通过一次向下的调整来将其变成一个堆
堆排序的过程
1.建立堆(检查每个父节点和它的孩子结点)
2.得到堆顶元素,为最大元素
3.去掉堆顶,将堆最后一个元素放在堆顶,此时可通过一次调整重新使堆有序
4.堆顶元素为第二大元素
5.重复步骤3,直到堆变空
向下调整的函数实现
def sift(li, low, high):
""" :param li:列表 :param low:堆的根结点位置 :param high:堆的最后一个元素的位置 :return: """
i = low
j = 2 * i + 1
tmp = li[low]
while j <= high:
if j + 1 <= high and li[j+1] > li[j]:
j = j + 1
if li[j] >tmp:
li[i] = li[j]
i = j
j = 2 * i + 1
else:
li[i] = tmp
break
else:
li[i] = tmp
堆排序的实现
时间复杂度为:O(ologn)
def sift(li, low, high):
""" :param li:列表 :param low:堆的根结点位置 :param high:堆的最后一个元素的位置 :return: """
i = low
j = 2 * i + 1
tmp = li[low]
while j <= high:
if j + 1 <= high and li[j+1] > li[j]:
j = j + 1
if li[j] >tmp:
li[i] = li[j]
i = j
j = 2 * i + 1
else:
li[i] = tmp
break
else:
li[i] = tmp
def heap_sort(li):
n = len(li)
for i in range((n-2)//2, -1, -1):
sift(li, i, n-1)
for i in range(n-1, -1, -1):
li[0], li[i] = li[i], li[0]
sift(li, 0, i - 1)
li = [i for i in range(100)]
import random
print(li)
heap_sort(li)
print(li)
堆排序中的topk问题 现在有n个数,设计算法得到前k大的数。(k
def sift(li, low, high): i = low j = 2 * i + 1 tmp = li[low] while j <= high: if j + 1 <= high and li[j+1] < li[j]: j = j + 1 if li[j] < tmp: li[i] = li[j] i = j j = 2 * i + 1 else: break li[i] = tmp def topk(li, k): heap = li[0:k] for i in range((k-2)//2, -1, -1): sift(heap, i, k-1) for i in range(k, len(li)-1): if li[i] > heap[0]: heap[0] = li[i] sift(heap, 0, k-1) for i in range(k-1, -1, -1): heap[0], heap[i] = heap[i], heap[0] sift(heap, 0, i-1) return heap import random li = list(range(1000)) random.shuffle(li) print(topk(li, 10))
本文《堆排序(heap-sort)》版权归fiveym所有,引用堆排序(heap-sort)需遵循CC 4.0 BY-SA版权协议。