一 概念:
满二叉树:每一个结点或者是一个分支结点,并恰好有两个非空子结点;或者是叶结点。
完全二叉树:从根结点起,每一层从左至右填充。
二叉树的性质:
<1> 二叉树中,第i层的节点最多有2(i-1)个。
<2> 深度为k的二叉树最多有2k-1个节点。
<3> 二叉树中,叶子节点树为N1个,度为2的节点有N2个,那么N1=N2+1。
<4> 具有N个结点的二叉树深度为(Log2 N)+1层。
<5> N个结点的完全二叉树如何用顺序存储,对于其中的一个结点i,存在以下关系,2*i是结点i的父结点。i/2是结点i的左孩子。(i/2)+1是结点i的右孩子。
二 二叉树的抽象数据类型:
template <typename E>class BinNode{
public:
virtual ~BinNode();
virtual E& element()=0;
virtual void setElement(const E&)=0;
virtual BinNode* left() const=0;
virtual void setLeft(BinNode*)=0;
virtual BinNode* right() const=0;
virtual void setRight(BinNode*)=0;
virtual bool isLeaf()=0;
};
三 遍历二叉树
(1)前序遍历:先打印根结点,接下来打印所有左子树的结点,最后打印所有右子树的结点。
//递归写法
template<typename E>
void preorder(BinNode<E>* root){
if(root==NULL)return;
visit(root);
preorder(root->left());
preorder(root->right());
}
//非递归写法
void preorder2(BinNode<E>* root){
stack<BinNode<E>*>st;
BinNode<E>* cur=root;
if(cur==NULL)return;
while(!st.empty()||cur)
{
if(cur)
{
visit(cur);
st.push(cur);
cur=cur->left();
}
else
{
cur=st.top();
st.pop();
cur=cur->right();
}
}
}
(2)中序遍历:先打印左子树的所有结点,再打印根结点,再打印右子树的所有结点。
//递归写法
template<typename E>
void inorder(BinNode<E>* root){
if(root==NULL)return;
inorder(root->left());
visit(root);
inorder(root->right());
}
//非递归写法
void inorder2(BinNode<E>* root){
stack<BinNode<E>*>st;
BinNode<E>* p=root;
while(!st.empty()||cur)
{
if(cur)
{
st.push(cur);
cur=cur->left();
}
else
{
cur=st.top();
st.pop();
visit(cur);
cur=cur->right();
}
}
}
(3)后序遍历:先打印左子树的所有结点,再打印右子树的所有结点,最后打印根结点。
//递归写法
template<typename E>
void postorder(BinNode<E>* root){
if(root==NULL)return;
postorder(root->left());
postorder(root->right());
visit(root);
}
//非递归写法
void postorder(BinNode<E>* root)
{
BinNode<E>* preNode=NULL,curNode;
curNode=root;
stack<BinNode<E>*>st;
if(curNode==NULL)return;
st.push(curNode);
while(!st.empty())
{
curNode=st.top();
if((curNode->left()==NULL&&curNode->right()==NULL)||
(preNode!=NULL&&(curNode->left()==preNode||curNode->right()==preNode)))
{
visit(curNode);
st.pop();
preNode=curNode;
}
else
{
if(curNode->right())st.push(curNode->right());
if(curNode->left())st.push(curNode->left());
}
}
}