二叉树理论
二叉树种类:
满二叉树 每一层都达到了最大结点数,深度为k的满二叉树有2^k-1个结点
完全二叉树 除了最底层没有填满,并且最底层的结点都应该在最左边的位置。
二叉树的遍历:
1.深度优先遍历
前序 中左右
中序 左中右
后序 左右中
递归:交换顺序即可实现
cout<<root->val; travel(root->left); travel(root->right);
2.广度优先遍历
借助队列实现,每次每次出队一个结点,将他的左右孩子入队(NULL不执行),知道队列为空。
二叉树的翻转:
一般采用前序和后序遍历翻转,中序遍历的话会使一个结点翻转两次。
void reverse(node){
swap(node->left,node->right); //交换两个结点地址的函数 中
reverse(node->left); 左
reverse(node->right); 右
}
二叉树的深度:
(深度与二叉树的高度有关) 因此可以采用后序遍历求高度
1.最大深度:返回 max(leftheight,rightheight)+1;
int getnum(node){
if(node==NULL) return 0;
int leftheight=getnum(node->left); 左
int rightheight=getnum(node->right); 右
int sum=leftheight+rightheight+1; 根
return sum;
2.最小深度:前提左右孩子都不为空。
因此会做一个判断:node的右孩子为空,左孩子不为空。 那么leftheight+1
反之rightheight+1
最后返回min(rightheight,leftheight)+1
完全二叉树的结点个数:
普通二叉树:后序遍历求左右孩子的结点个数,然后返回+1
完全二叉树:左子树,右子树肯定会有一棵子树是满二叉树,此时可以使用2^k-1求得
先求左右孩子的深度,若深度相等则 返回2^k-1
否则继续遍历直到找到满二叉树位置。 (一个结点的树也是满二叉树,所以到最后一定可以找到)
最后返回leftnum+rightnum+1;
中序与后序构建二叉树:
inorder=[10,9,4,15,20,7]
postorder=[7,9,19,10,15,4]
步骤: 1.通过后序数组最后一个元素,得到根节点,root->val=postorder[lens-1]
2.在中序数组中找到,后序数组中的最后一个值,将中序遍历分为左右两大块。leftorder rightorder
3.通过leftorder rightorder的元素个数,将后序遍历从前开始分割成两块,每次都抛去最后一个(因为已经使用了)
4.反复递归,直到postorder的长度变为0为止。
简单一点来说:
1.获取后序数组最后一个元素target,切割中序数组;获取target在中序中的位置index,切割后序数组。反复递归,直到postorder的长度为0,代表无元素。
void Create(node,inorder,postorder,inSize,postSize){
if(postSize==0){return;}
node=new(TNode); //赋值前开辟空间,否则会指向野指针。
int target=postorder[postSize-1];
node->val=target;
int index=(inorder,target); ///获取中序数组的位置
Create(node->left,inorder,postorder,index,index);
Create(node->right,inorder+index+1,postorder+index+1,postSize-index-1);
注意:这里中序的两个区间不包含index。
第一次接触数据结构与算法,请见谅。