在算法实现方面要求,
1,熟练掌握二叉树的递归和非递归遍历
递归遍历
void preorder(BiTnode *p)
{ if (p!=NULL)
{ printf ("%6c",p->data); /*访问根结点*/
preorder(p->lchild);
/*按先根次序遍历左子树*/
preorder(p->rchild);
/*按先根次序遍历右子树*/
}
}/* preorder */
void inorder( BiTnode *p)
{ if (p!=NULL)
{ inorder(p->lchild);
/*中根遍历左子树*/
printf("%6c",P->data);
/*访问根结束*/
inorder(p->rchild);
/*中根遍历右子树*/
}
}/* inorder */
Void postorder( BiTnode *p)
{ if (p!=NULL)
{ postorder(p->lchild);
/*后根遍历左子树*/
postorder(p->rchild);
/*后根遍历右子树*/
printf("%6c",p->data);
/*访问根结点*/
}
} /* postorder */
非递归遍历
void preOrder(TreeNode t) { //先序遍历
Stack<TreeNode> s = new Stack<>();
while(t != null || !s.isEmpty()) {
while(t != null) {
printf(t.val);
//第一次碰到就访问结点
s.push(t);
//压栈保存,左边访问完了再访问右节点
t = t.left;
}
if(!s.isEmpty()) {
t = s.pop();
t = t.right;
//当上述循环推出,说明左子树全访问完了,
则把父结点弹出,准备访问右子树
}
}
}
void inOrder(TreeNode t) {
//中序,与先序很像,只是在第二次碰到结点才访问
Stack<TreeNode> s = new Stack<>();
while(t != null || !s.isEmpty()) {
while(t != null) {
s.push(t);
//第一次碰到不访问,只保存
t = t.left;
}
if(!s.isEmpty()) {
t = s.pop();
printf(t.val);
//左子树访问完了,弹出父结点,第二次碰到则访问
t = t.right;
//准备访问右子树
}
}
}
void lastOrder(TreeNode t) { //后序与上述两种方式有区别,只有左右结点都被访问,当前结点才能被访问
TreeNode preNode = null; //记录上一次访问结点
Stack<TreeNode> s = new Stack<>();
s.push(t); //压入根节点,这货铁定最后访问,万年栈底元素
while(!s.isEmpty()) {
TreeNode current = s.peek(); //获取栈顶元素
//当前结点左右结点均为空,或左右结点不都为空但已经都被访问则当前结点可以访问了
(即上次访问结点preNode == 左/右结点)
//由于压栈顺序是先右后左,所以当前结点的孩子们访问时必然是先左后右. preNode == left说明当前结点只有左孩子且已被访问,==right说明有两个孩子且左右均已访问
if((current.left==null&¤t.right==null)||(preNode!=null&&(preNode==current.left||preNode==current.right))){
System.out.println(current.val);
s.pop();
preNode = current;
//每访问一个结点都记录一下,以便下次判断结点的左右孩子是否已被访问
}
else if(current.right != null)
//若不满足上述条件,则把当前结点的孩子以先右后左的顺序压栈,这样访问时就是先左后右了 s.push(current.right);
else if(current.left != null)
s.push(current.left);
}
}
2,解决实际问题
1)计算树的层数/深度/树高
int Depth(BiTree *t)
{ //*t为指向二叉树根结点的的指针
if(t=NULL) ruturn (0); //若树为空,则高度为0
else
{ hl=depth(t->lchild); //求左子树高度
hr=depth(t->rchild); //求右子树高度
if(hl>hr) //树高为左右子树高度大者加1
return(hl+1);
else
return(hr+1);
}//else
}//PreTreeDepth
2)节点的度/节点的分叉数
变相求一个父节点的节点个数。同3)
3)查找满足条件的节点/叶子节点的个数
Void injishu( BiTnode *t)
{ if (t!=NULL)
{ injishu(t->lchild); /*中根遍历左子树*/
printf("%6c",t->data); /*访问根结点*/
m++; /*结点计数,m为全局变量*/
if((t->lchild==NULL)&&(t->rchild==NULL))
n0++;/*叶结点计数*/
injishu(t->rchild); /*中根遍历右子树*/
}
} /* injishu */