1.求叶节点个数(包含于4.)
2.由已知中序、先序序列建树
3.求高度
4.求度为1/2/0的节点个数
5.交换二叉树左右孩子(镜面反射二叉树)
6.查找先序序列中第k个节点
7.根据先序、后序确定满二叉树
8.判断两个二叉树是否相似
9.二叉树线索化
10.在中序线索二叉树里查找指定节点在后序的前驱节点
11.叶节点的带权路径长度之和
2.由已知中序、先序序列建树
算法思想:设先序序列为pre[],中序序列为mid[],先序序列第一个元素为根节点,在中序序列中找到根节点,左边为左子树,右边为右子树,求出左右子树的长度。更新序列首位,进行递归。
btree creatree(pre[],mid[],int f1,int r1,int f2,int r2){
//f1,r1为pre的先序序列首尾指针,f2,r2为中序序列mid的首尾指针
int i;
root=new btnode;
root->data=pre[f1]->data;
for(i=f2;pre[f1]!=mid[i];i++);//找到根节点在中序序列的位置
len1=i-f2;//左子树长度
len2=r2-i;//右子树长度
if(len1) //左子树存在
root->lchild=creatree(pre[],mid[],f1+1,f1+len1,f2,f2+len1-1);
else root->lchild=null;
if(len2)//右子树存在
root->rchild=creatree(pre[],mid[],r1-len2+1,r1,r2-len2+1,r2);
else root->rchild=null;
return root;
}
3.求高度
算法思想:左右子树较高的高度+1(后序遍历)
int d;//全局变量
int depth(btree t){
if(t==null) return 0;
int dl,dr;
dl=depth(t->lchild);
dr=depth(t->rchild);
d=dl>dr?dl:dr;
return d;
}
或者:先序遍历。
void depth(btree t,int d,int level){
//level当前层,d为深度
if(level>d) d=level;
depth(t,d,level+1);
depth(t,d,level+1);
}
4.求度为0/1/2的节点个数
int num_degree(btree t,int degree){
if(degree==0){
if(t==null) return 0;
if(t->lchild==null&&t->rchild==null)
return 1+num_degree(t->lchild,0)+num_degree(t->rchild,0);
}
if(degree==1){
if(t==null) return 0;
if(t->lchild&&!t->rchild)
return 1+num_degree(t->lchild,1);
if(t->rchild&&!t->lchild)
return 1+num_degree(t->rchild,1);
}
if(degree==2){
if(t==null) return 0;
if(t->lchild&&t->rchild)
return 1+num_degree(t->lchild,2)+num_degree(t->rchild,2);
}
}
5.镜面二叉树
算法思想:后序遍历。交换左右子树,再交换左右孩子
btree mirror_tree(btree t){
if(t){
mirror_tree(t->lchild);
mirror_tree(t->rchild);
btree temp;
temp=t->lchild;
t->lchild=t->rchild;
t->rchild=temp;
}
}
6.查找先序序列中第k个节点
算法思想:
int i=0;//全局变量
btree pre_k(btree t,int k){
if(t){
if(k==i) return t;
i++;
pre_k(t->lchild,k);
pre_k(t->rchild,k);
}
}
7.根据一满二叉树的先序序列,确定后序序列
算法思想:先序序列pre[],后序序列post[]。
对于满二叉树,任一节点的左右指数含有相等的节点数,同时,先序序列的第一个节点作为后序序列的最后一个节点,由此得到递归模型:
递归出口:r1< f1.
递归主体:
f(pre,f1,r1,post,f2,r2) :
post[r2]=pre[f1];
取中间位置half=(r1-f1);
对左子树递归 f(pre,f1+1,f1+half,post,f2,f2+half-1);
对右子树递归f(pre,f1+half+1,r1,post,f2+half,r2-1);
void pretopost(elemtype pre[],elemtype post[],int f1,int r1,int f2,int r2){
if(r1<f1) return;
post[r2]=pre[f1];
int half=(r1-f1)/2;
pretopost(pre,post,f1+1,f1+half,f2,f2+half-1);
pretopost(pre,post,f1+half+1,r1,f2+half,r2-1);
}
8.判断两个二叉树是否相似
算法思想:先序
int similar(btree t1,btree t2){
if(t1==t2==null) return 1;
else if(t1==null||t2==null) return 0;
else{
return similar(t1->lchild,t2->lchild)*similar(t1->rchild,t2->rchild);
}
}
9.二叉树线索化
//线索二叉树的结构:
typedef struct threadnode{
elemtype data;
struct threadnode *lchild,*rchild;
int ltag,rtag;
}threadnode,*threadtree;
//中序线索化
void inthread(threadtree &p,threadtree &pre){
if(p){
inthread(p->lchild,pre);
if(p->lcihld==null){//左指针为空
p->lchild=pre;//指向前驱
p->ltag=1;//标记
}
if(pre!=null&&p->rchild==null){//右指针为空且不是首个节点(pre为空)
pre->rchild=p;//建立前驱节点的后继
p->rtag=1;//标记
}
pre=p;//标记当前节点为刚访问过的节点
inthread(p->rchlid,pre);
}
}
//主程序
void creatinthread(threadtree t){
threadtree pre=null;//初始化
if(t){
inthread(t,pre);
pre->rchlid=null;
pre->rtag=1;
}
}
//求首节点
threadnode *firstnode(threadnode *p){
while(p->ltag==0) p=p->lchild;
return p;
}
//求后继
threadnode *nextnode(threadnode *p){
if(p->rtag==0) return firstnode(p->rchild);
else return p->rchild;
}
//非递归且不需要栈的遍历算法
void inorder(threadtree t){
for(threadnode *p=firstnode(t);p!=null;p=nextnode(p))
visit(p);
}
10.在中序线索二叉树里查找指定节点在后序的前驱节点
11.叶节点的带权路径长度之和