一、准备知识
完全二叉树:每个节点的度最大为2,除了最后一层之外的其他每一层都被完全填充,并且所有结点都保持向左对齐的树
堆的结构可以分为大根堆和小根堆,是一个完全二叉树
大根堆:每个结点的值都大于其左孩子和右孩子结点的值
小根堆:每个结点的值都小于其左孩子和右孩子结点的值
已知索引为i的数,那么
1.父结点索引:(i-1)/2(这里计算机中的除以2,省略掉小数)
2.左孩子索引:2*i+1
3.右孩子索引:2*i+2
二、流程
若要从小到大排序,则用大根堆
- 首先将无序数组构造成一个大根堆
- 将第一个元素值与最后一个位置的值交换,并固定不再参与排序
- 将其余元素重新构造大根堆
- 重复步骤2
若要从大到小排序,则用小根堆,步骤同大根堆
三、具体操作
-
将给定无序数组构造成一个大根堆
arr={3,6,8,5,7}
方法:按顺序插入节点并将其与父节点进行比较,若小于父节点值则继续插入,否则将其与父节点进行交换继续向上检查,直到符合大根堆
-
将第一个元素值与最后一个位置的值交换,并固定不再参与排序
此时, arr={8,7,6,3,5}
8与5进行交换,此时最大数8已经来到末尾,则固定不动
arr={5,7,6,3,8} -
将其余元素重新构造大根堆
对顶端的数据进行操作即可
拿顶端的数与其左右孩子较大的数进行比较,如果顶端的数大于其左右孩子较大的数,则停止,如果顶端的数小于其左右孩子中较大的数,则交换,然后继续与下面的孩子进行比较
-
此时arr={7,5,6,3,8}
将7与3进行交换,并固定7
arr={3,5,6,7,8} -
将其余元素重新构造大根堆
-
此时arr={6,5,3,7,8}
交换6与3,固定6
此时arr={3,5,6,7,8} -
将剩余元素3,5构造大根堆为5,3,此时arr={5,3,6,7,8}
-
交换5与3,固定5,此时arr={3,5,6,7,8}
-
结束
四、python代码实现
代码中主要包含三个函数:
- 构造初始大根堆
- 将剩余元素构造成大根堆
- 交换数组中两个元素的值