转:https://xiaozhuanlan.com/topic/5036471892
二叉树性质
1)在二叉树的第i层上最多有2i-1 个节点 。(i>=1)
2)二叉树中如果深度为k,那么最多有2k-1个节点。(k>=1)
3)n0=n2+1 n0表示度数为0的节点数,n2表示度数为2的节点数。
4)在完全二叉树中,具有n个节点的完全二叉树的深度为[log2n]+1,其中[log2n]是向下取整。
5)若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点有如下特性:
(1) 若 i=1,则该结点是二叉树的根,无双亲, 否则,编号为 [i/2] 的结点为其双亲结点;
(2) 若 2i>n,则该结点无左孩子, 否则,编号为 2i 的结点为其左孩子结点;
(3) 若 2i+1>n,则该结点无右孩子结点, 否则,编号为2i+1 的结点为其右孩子结点。
二叉树遍历
前序遍历 :通俗的说就是从二叉树的根结点出发,当第一次到达结点时就输出结点数据,按照先向左再向右的方向访问。
中序遍历 :就是从二叉树的根结点出发,当第二次到达结点时就输出结点数据,按照先向左再向右的方向访问。
后序遍历 :就是从二叉树的根结点出发,当第三次到达结点时就输出结点数据,按照先向左再向右的方向访问。
层序遍历 :层次遍历就是按照树的层次自上而下的遍历二叉树。
*虽然二叉树的遍历过程看似繁琐,但是由于二叉树是一种递归定义的结构,故采用递归方式遍历二叉树的代码十分简单。
void PreOrderTraverse(BiTree T) { if(T==NULL) return; printf("%c", T->data); /*显示结点数据,可以更改为其他对结点操作*/ PreOrderTraverse(T->lchild); /*再先序遍历左子树*/ PreOrderTraverse(T->rchild); /*最后先序遍历右子树*/ } /*二叉树的中序遍历递归算法*/ void InOrderTraverse(BiTree T) { if(T==NULL) return; InOrderTraverse(T->lchild); /*中序遍历左子树*/ printf("%c", T->data); /*显示结点数据,可以更改为其他对结点操作*/ InOrderTraverse(T->rchild); /*最后中序遍历右子树*/ } /*二叉树的后序遍历递归算法*/ void PostOrderTraverse(BiTree T) { if(T==NULL) return; PostOrderTraverse(T->lchild); /*先后序遍历左子树*/ PostOrderTraverse(T->rchild); /*再后续遍历右子树*/ printf("%c", T->data); /*显示结点数据,可以更改为其他对结点操作*/ }
将二叉树按中序遍历得到一个有序的数组结果,某个节点元素的前后相邻的节点即为前驱节点,后区节点
前驱节点
1:如果当前节点的左子树不为空,那么该点的前驱节点为该点左子树中最右的节点。
2:如果当前节点的左子树为空,那么该点的前驱节点为从该点往上延伸,如果延伸到的点为其父亲节点的右孩子,那么这个父亲节点就是该点的前驱节点。
后驱节点
1:如果当前节点的右子树不为空,那么该点的后驱节点为该点右子树中最左的节点。
2:如果当前节点的右子树为空,那么该点的后驱节点为从该点往上延伸,如果延伸到的点为其父亲节点的左孩子,那么这个父亲节点就是该点的后驱节点。
struct node { node left;//左孩子 node right;//右孩子 node parent;//父亲节点 int value; }; node getfristornode(node heap)//heap代表当前要找前驱节点的节点 { if(heap==null)//如果当前节点为空,返回空 return heap; if(heap.left!=null)//如果当前节点左子树不为空,那么该节点的后继节点为左子树中最右的节点 return getrightmost(heap.left);//找到左子数树中最右的节点,并返回 else //如果程序到达这里,说明当前节点的左子数为空 { node parent=heap.parent; //第一个条件就是判断那种特殊情况的,一直延伸到当前节点没有父亲节点时,那么parent为空,这个条件不满足,函数返回空 //第二个条件是判断当前节点是否为该父亲节点的右孩子,如果不是,继续执行下面的代码,如果是,说明这个父亲节点就是heap节点的前驱节点 while (parent!=null&&heap!=parent.right) { heap=parent; parent=heap.parent; } return parent; } } //这个函数是求左子树中最右的节点的函数 getrightmost(node heap) { while (heap!=null) heap=heap.right; return heap.parent; }
上面是前驱节点的查找方式,后区节点基本相同,左右换下。