完全二叉树
一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。

完全二叉树判定算法思路
判断一棵树是否是完全二叉树的思路:
- 如果树为空,则直接返回错
- 如果树不为空:层序遍历二叉树
- 如果一个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列;
- 如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
- 如果遇到一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空;则该节点之后的队列中的结点都为叶子节点;该树才是完全二叉树,否则就不是完全二叉树;
堆(heap)

又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。
堆需要满足的条件:
1. 必须是二叉树,且必须是完全二叉树
2. 各个父节点必须大于或小于左右结点, 其中最顶层的根结点必须是最大或者最小的
1.最大堆的实现
1.初始化堆
堆可以使用list实现,就是按照层序遍历顺序将每个节点上的值存放在数组中。
parent = i, # i 从 0 开始
left = 2 * i + 1
right = 2 * i + 2

2.在堆中增加元素

3.删除根节点,并重建堆结构

# 最大堆的实现
class MaxHeap():
def __init__(self, maxSize=None):
self.maxSize = maxSize
self.li = [None] * maxSize
self.count = 0
def length(self):
# 求数组的长度
return self.count
def show(self):
if self.count <= 0:
print('null')
else:
print(self.li[: self.count])
def add(self, value):
if self.count >= self.maxSize: # 判断是否数组越界
raise Exception('full')
self.li[self.count] = value # 将新节点增加到最后
self._shift_up(self.count) # 递归构建大堆
self.count += 1
def _shift_up(self, index):
# 往大堆中添加元素,并保证根节点是最大的值:
# 1.增加新的值到最后一个结点,在add实现; 2.与父节点比较,如果比父节点值大,则交换
if index > 0:
parent = (index - 1) // 2 # 找到根节点
if self.li[index] > self.li[parent]: # 交换结点
self.li[index], self.li[parent] = self.li[parent], self.li[index]
self._shift_up(parent) # 继续递归从底往上判断
def extract(self):
# 弹出最大堆的根节点,即最大值
# 1.删除根结点,将最后一个结点作为更结点 ; 2.判断根结点与左右结点的大小,交换左右结点较大的
if not self.count:
raise Exception('null')
value = self.li[0]
self.count -= 1
self.li[0] = self.li[self.count] # 将最后一个值变为第一个
self._shift_down(0)
return value
def _shift_down(self, index):
# 1.判断是否有左子节点并左大于根,左大于右;2.判断是否有右子节点,右大于根
left = 2 * index + 1
right = 2 * index + 2
largest = index
# 判断条件
if left < self.length() and self.li[left] > self.li[largest]:
largest = left
if right < self.length() and self.li[right] > self.li[largest]:
largest = right
if largest != index: # 将 两者交换
self.li[index], self.li[largest] = self.li[largest], self.li[index]
self._shift_down(largest)
import numpy as np
m = MaxHeap(10)
np.random.seed(123)
num = np.random.randint(100, size=10) # 创建随机的10个数
print(m.length())
for i in num:
m.add(i)
m.show()
print(m.length())
for i in range(5):
print(m.extract(), end=' ,')
本文详细介绍了完全二叉树的概念与判定算法,以及最大堆的数据结构实现,包括初始化、元素添加与删除等关键操作,展示了如何通过Python代码构建和维护最大堆。
889

被折叠的 条评论
为什么被折叠?



