二叉树用数组描述,当数据很少时非常浪费空间,所以一般都用链表描述。
template<class T>
struct binaryTreeNode
{
T element;
binaryTreeNode<T>* leftChild, *rightChild;//左子树和右子树。
binaryTreeNode() {leftChild=rightChild=NULL;}
binaryTreeNode(const T& theElement) {element(theElement);leftChild=rightChild=NULL;}
binaryTreeNode(const T& theElement,binaryTreeNode<T> *theLeftChild,binaryTreeNode<T> *theRightChild)
{
element(theElement);
leftChild=theLeftChild;
rightChild=theRightChild;
}
}
二叉树的链表表示没有指向父节点的指针,若需要可以增加,但一般用不到。
template<class T>
T visit(binaryTreeNode<T>*t)
{
return t->element;
}
template<class T>
void preOrder(binaryTreeNode<T>*t)
{//前序遍历二叉树*t
if(t!=NULL)
visit(t);
preOrder(t->leftChild);
preOrder(t->rightChild);
}
以上为二叉树的前序遍历,该遍历用递归函数实现,代码简单,前序遍历优先查看根节点,然后查看左子树,然后查看右子树。从根节点开始对每个子树执行同样的操作。(注意如果根节点的左子树不是叶节点,则优先查看左子树的左子树,而不是直接去查看根节点的右子树)
template<class T>
void inOrder(binaryTreeNode<T>*t)
{//中序遍历二叉树*t
if(t!=NULL)
preOrder(t->leftChild);
visit(t);
preOrder(t->rightChild);
}
该函数中序遍历二叉树,首先查看左树,再查看根节点,最后查看右节点。如果左树不为叶节点,那么继续查看左树的左树。
template<class T>
void postOrder(binaryTreeNode<T>*t)
{//后序遍历二叉树*t
if(t!=NULL)
preOrder(t->leftChild);
preOrder(t->rightChild);
visit(t);
}
后序遍历,首先查看左节点,在查看右子树,在查看左子树,最后查看根节点。
之前说过,二叉树可以用来表示计算表达式,那么三种遍历方式分别对应不同的组合规则,但是由于+,-,*,\有自己的优先级,所以有时会产生歧义,最好的办法就是在每一步操作上都加括号。
改变之后的中序遍历代码如下:
template<class T>
void infix(binaryTreeNode<T>*t)
{
if(t!=NULL)
{
cout<<'(';
infix(t->leftChild);
cout<<t->element;
infix(t->rightChild)
cout<<')';
}
}
下面是层次遍历
template<class T>
void levelOrder(binaryTreeNode<T>*t)
{//层次遍历二叉树*t
arrayQueue<binaryTreeNode<T>*t> q;
while(t!=NULL)
{
visit(t);
if(t->leftChild!=NULL)
q.push(t->leftChild);
if(t->rightChild!=NULL)
q.push(t->rightChild);
try{t=q.front();}
catch(queueEmpty){return;}
q.pop();
}
这可能最容易理解的遍历方式了,从左到右按照编号方式进行遍历。
int height() const{ return height(root);}
template <class E>
int height(binaryTreeNode<E> *t)
{//返回*t的树的高度
if(t==NULL)
return 0; //空树
int h1=height(t->leftChild);//左树高
int hr=height(t->rightChild);//右树高
if(h1>hr)
return ++hl;
else
return ++hr;
}
这个判断树高的代码有点那么难以理解,但是如果你理解了,其实也就那样。判断的原理是每一个根节点的高度等于其左子树和右子树最高的那一个高度在加上1,该代码从左叶节点开始向上搜索判断。