2020/10/25刷题过程中,堆的题目不会,所以在此总结,供大家学习
队列,栈等都是一对一的线性结构,可现实生活中还有恩多一对多的情况,我们称之为树
本篇文章涉及的名词汇总: | 具体含义 |
n个结点 | 每个圆圈代表一个结点 |
深度 | 第一层/第二层/第三层…,树中结点的最大深度称为深度depth |
满二叉树 | 所有分支节点都存在左子树和右子树
|
|
|
叶节点/终端结点 | 度为0的节点称为叶结点 |
非叶节点/非终端结点 | 度不为0的节点称为非叶结点 |
度 | 结点拥有的子树数称为结点的度 |
排序算法稳定性 | 稳定就是相同大小的元素,排序之后他们的顺序和原来一致。 例如下面的键值对数据: A:1 B:2 C:1 现在按数值排序,因为A和C的值是一样的,可以排成: C:1 A:1 B:2 也可以排成: A:1 C:1 B:2 第二种结果就是稳定的排序结果,因为在输入数据中A在C前面,排序结果中A也在C前面。 |
树的种类:满二叉树、完全二叉树
完全二叉树:
1)定义:对所有的节点按照满二叉树进行排序,编号和满二叉树位置完全相同,则称之为完全二叉树
2)区别:满二叉树是完全二叉树,完全二叉树不一定是满二叉树
3)性质:
堆是什么:
堆是一颗完全二叉树结构
1)
分两种:
大根堆:
Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆
1)堆顶的关键字肯定是所有关键字中最大的
大根堆是大根树的一种
小根堆:
Key[i]<=Key[2i+1]&&key>=key[2i+2]称为小顶堆
1)堆顶的关键字肯定是所有关键字中最小的
堆排序(Heap Sort)
可以想象成叠罗汉,最上面的肯定是最轻的人;
利用大小根堆顶记录的关键字这一特性
不稳定
步骤:
1)将待排序元素构造成一个大顶堆。此时,堆顶就是最大元素了
2)将堆顶与堆尾交换。堆尾就是最大值,然后将剩余的n-1个数值进行构造成新堆
3)如此反复执行,便能得到一个有序序列了
注意点:
1)为什么是n/2;因为都是有孩子的结点,其实就是对每个非叶结点当作根结点,将其和其子树调整成大顶堆;
堆排序代码
class Solution4:
@staticmethod
def swap(nums, i, j):
nums[i], nums[j] = nums[j], nums[i]
def heapify(self, nums, i, size):
left, right = 2 * i + 1, 2 * i + 2
largest = i
if left < size and nums[left] > nums[largest]:
largest = left
if right < size and nums[right] > nums[largest]:
largest = right
if largest != i:
self.swap(nums, i, largest)
self.heapify(nums, largest, size)
def build_heap(self, nums, k):
# 从最后一个非叶子节点开始堆化
for i in range(k // 2 - 1, -1, -1):
self.heapify(nums, i, k)
def getLeastNumbers(self, arr, k: int):
if not arr or k <= 0: return []
if len(arr) <= k: return arr
heap = arr[:k]
self.build_heap(heap, k)
for i in range(k, len(arr)):
if arr[i] < heap[0]:
heap[0] = arr[i]
self.heapify(heap, 0, k)
return heap
作者:wu-xian-sen-2
链接:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/solution/python3-ji-chu-pai-xu-suan-fa-zong-jie-by-wu-xian-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。