树是一种数据结构 比如 目录结构
树是一种可以递归定义的数据结构
树是由n个节点组成的集合:
- 如果 n=0, 那这是一颗空树
- 如果 n>0, 那存在1个节点作为树的根节点,其他节点可以分为m个集合,每个集合本身又是一棵树
根节点、叶子节点
树的深度(高度)
树的度
孩子节点/父节点
子树
E是I的父节点,I是E的子节点
二叉树
- 二叉树: 度不超过2的树
- 每个节点最多由两个孩子节点
- 两个孩子节点被区分为左孩子节点和有孩子节点
满二叉树:一个二叉树,如果每一个层的结点树都达到最大值,则这个二叉树就是满二叉树
完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树
二叉树的存储方式
链式存储方式
顺序存储方式
父节点和左孩子节点的编号下标由什么关系?
0-1 1-3 2-5 3-7 4-9 i的值
i -> i*2+1
父节点和右孩子节点的编号下标由什么关系?
0-2 1-4 2-6 3-8 4-10 i的值
i -> 2*i+2
假设孩子的节点是i 父亲的节点是(i-1)/2
堆排序
堆: 一种特殊的完全二叉树结构
- 大根堆: 一颗完全二叉树,满足任一节点都比其孩子节点大
- 小根堆: 一颗完全二叉树,满足任一节点都比其孩子节点小
5比8小
堆的向下调整性质
假设根节点的左右子树的都是堆,但根节点不满足的性质
可以通过一次向下的调整来将变成一个堆
当根节点的左右子树都是堆时,可以通过一次向下的调整来将其变换成一个堆
9把2推翻了,2可以当区长吗?不能那么就把8推上区,因为8比5大,2能当镇长吗?不能,把6推上去,就是下图了
建立一个堆,农村包围城市
堆排序过程
- 建立堆
- 得到堆顶元素,为最大元素
- 去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序
- 堆顶元素为第二大元素
- 重复步骤3,知道堆变空
else : #tmp 更大,把tmp放到i的位置上 假如堆点是6
li[i] = tmp # 6放到原来8的
break
else: #就是2没法和别的比了,就放到该去的地方去
li[i] = tmp #把tmp放到叶子节点上去
扫描 这些圈圈
循环3、9、1、8、6
def sift(li,low,hight):
#li 列表
# low: 堆的根节点位置 第一个元素
# higth 堆的指向最后一个元素的位置
# return
#i->指当前一层 和下一个层
#i 是市长
#i要是大于higth 退出了
#n-1 就是是整个堆元素最后一个下标
def sift(li,low,hight):
i = low
#找孩子 左孩子
j = 2 * i +1
tmp = li[low] #把堆顶存起来
while j <= hight: #只要j位置有数
#右孩子要右,右孩子比较大 并且右孩子大于左孩子 右孩子不越界 j+1 <=hight
if j+1 <=hight and li[j+1] > li[j]:
#j 指向右孩子 这个指的是两个孩子更大的数
j = j + 1
if li[j] > tmp: #目前要是,tmp大就放过去,还是j大放上面去
li[i] = li[j]
i = j #可以交换了 现在j等于新的i i等于原来的j 往下一层
j = 2 * i + 1
else : #tmp 更大,把tmp放到i的位置上 假如堆点是6
li[i] = tmp # 6放到原来8的
break
else: #就是2没法和别的比了,就放到该去的地方去
li[i] = tmp #把tmp放到叶子节点上去
#最后非叶子节点
#n的最后一个下标是n-1,找他的父亲就孩子,(n-1-1)/2
#孩子下标是 n
#孩子找父亲 (n-1)/2 里面的n的最后一个下标是n-1 所有(n-1-1)/2 -> (n-2)/2
#倒序,-1,步长是-1
def heap_sort(li):
n = len(li)
for i in range((n-2)//2,-1,-1):
# i 表示建堆的时候调整的部分的根的下标
sift(li,i,n-1)
#建堆完成了 i=n-1指的最后一个元素的 倒叙
for i in range(n-1,-1,-1):
# i 指向当前堆的最后一个元素 li[0]堆顶 li[i]最后一个元素
li[0] , li[i] = li[i],li[0] #交换
sift(li,0,i-1) #i-1是新的high
li = [i for i in range(100)]
import random
random.shuffle(li)
print(li)
heap_sort(li)
print(li)
要不是左边,要不是右边,最多走的是树的高度层
时间复杂度 O(nlogn)
import heapq #优先队列的
import random
li = list(range(100))
random.shuffle(li)
print(li)
heapq.heapify(li) #建堆
n = len(li)
for i in range(n):
print(heapq.heappop(li), end=',')