在算法實現方面要求,
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 */