树的概念:
树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合.
节点的度: 一个节点含有的子树的个数称为该节点的度.
叶子结点或终端节点:度为0的节点.
树的度:一棵树中,最大的节点的度称为树的度.
树的深度或高度:树中节点的最大层次.
森林:由m(m>0)棵互不相交的树的集合称为森林.
二叉树的概念:
一颗二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两颗分别称为左子树和右子树的二叉树组成.
二叉树的特点:①.每个结点最多有两颗子树,即二叉树不存在度大于2的节点.
②.二叉树的子树有左右之分,其子树的次序不能颠倒.
特殊的二叉树:
①.满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树.也就是说,如果一个二叉树的层数为k,且结点总数为(2^k-1),则它就是满二叉树.
②.完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的.对于深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树.要注意满二叉树是一种特殊的完全二叉树.
二叉树的存储结构: 一般使用两种结构存储,一种顺序结构,一种链式结构.
二叉树的性质(默认根节点的层数为1):
①.一棵非空二叉树的第i层上最多有2^(i-1)个结点.
②.深度为h的二叉树的最大结点个数是2^h-1.
③.对于任意一棵二叉树,如果度为0其叶子结点个数为n0,度为2的分支结点个数为n2,则n0=n2+1.
④.具有n个结点的满二叉树的深度,h=log2(n+1)
顺序存储:就是使用数组存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间浪费.
( 二叉树顺序存储在物理上是一个数组,在逻辑上是一棵二叉树.)
堆的概念和结构: 现实生活中我们通常把堆(一种二叉树)使用顺序结构存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段.
一.向下调整算法(以建大堆为例): 前提: --> 子树已经是一个堆
①.起始位置(parent);
②.计算孩子(child)位置;
③.从两个孩子中选择一个最大值;
④.如果孩子(child)大于父节点(parent),交换,更新父节点(parent)和孩子节点(child),继续第③步;
⑤.如果没有孩子,或者父节点是 孩子中最大的,结束调整.
void shiftdown(HPDataType* array, int size, int parent) {
int child = 2 * parent + 1;
while (child < size) {
if (child + 1 < size&& array[child] < array[child + 1])
child++;
if (array[child] > array[parent]) {
swap(array, child, parent);
parent = child;
child = 2 * parent + 1;
}
else
break;
}
}
二.向上调整算法(以建大堆为例): 前提-->除过最后节点,其它节点构成的子结构已经是一个堆
①.起始位置(child);
②.计算父节点(parent)的位置;
③.比较起始位置(child)和父节点(parent)的大小,如果起始位置大于父节点,交换,更新起始位置,继续执行第②步;
④.如果没有父亲,或者起始位置(child)小于父节点(parent),则结束调整.
void shiftup(HPDataType* array, int child) {
int parent = (child - 1) / 2;//确定父节点的位置
while (child > 0) {
//前提是大根堆已经建好
if (array[child] > array[parent]) {
swap(array, child, parent);
child = parent;
parent = (child - 1) / 2;
}
else
break;
}
}
topK:从所有数据中找前k个最值
①.用前k个数据建立含有k个元素的堆
②.从第k+1个元素开始,每次堆顶元素比较,如果符合(array[i]>heapTop,或者array[i]<heapTop,(i>k))
条件,删除栈顶元素,符合条件的元素入堆
③.遍历完所有数据之后,堆中的元素就是前k个最值.
注意:找最小值,建大堆.相反找最大值,则建小堆.
删除:交换-->尾删-->向下调整
插入:尾插-->向上调整
**************************************************************************************************************************************
二叉树的遍历:前中后遍历顺序(所谓遍历是指沿着某条搜索路线,依次对书中的每个结点均做一次且仅做一次遍问.遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础)
①.前中后指的是当前节点的访问时机
前序:node , left , right
中序:left , node , right
后序:left , right ,node
②.三种遍历都是递归的遍历
③.三种遍历中,左子树始终优先于右子树访问