在二叉树中每个节点最多只能有两个子节点。即左子节点和有子节点。
在二叉树中最重要的操作应当是遍历。即按照某一顺序访问二叉树中的每一个节点。
一般有如下几种遍历方法
1:前序遍历,即先访问根几点,然后再访问左子节点,最后访问右子节点。
2:中序遍历,即先访问左子节点,然后再访问根节点,最后访问右子节点。
3:后序遍历,即先访问左子节点,然后再访问右子节点,最后访问根节点。
对于这三种遍历方法中的“*序“来说,都是针对于根节点的,按照根节点在遍历过程中的前中后来区分的。
这三种遍历方法都有两种不同的实现方式,循环和递归,递归实现起来要比循环简单的多。
除了上述三种遍历方法,还有一种是宽度优先遍历。即按照”层“的观点去访问二叉树。
二叉树有很多特殊的例子,比如二叉搜索树就是其中一个例子。在二叉搜索树中左子节点总是小于根节点,右子节点总是大于根节点。
我们可以在Log(n)的时间内根据指定的值在二叉树中找到一个节点。
我们可以根据一个前序遍历序列和一个中序遍历序列来重新构建出一个二叉树,代码如下:
//节点的定义
Struct BinaryTreeNode{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}
在二叉树的前序序列中第一个数一定是二叉树的根节点。
但是在中序序列中二叉树的根节点一定是在序列的中间位置,根节点左边的就是左子树,右边的就是右子树。
这样我们就可以用递归的方式来实现重建二叉树的操作。
BinaryTreeNode* Construct(int* preOrder,int* inOrder,int length){
if(preOrder == null or inOrder == null or length <= 0)
return null;
Return ConstructCore(preOrder,preOrder + length-1,inOrder,inOrder + length -1);
}
BinaryTreeNode* ConstructCore(int* startPreOrder,int* endPreOrder,int* startInOrder,int* endInOrder){
//前序遍历序列的第一个值是根节点的值
int rootValue = startPreOrder[0];
BinareTreeNode* root = new BinaryTreeNode();
root->m_nValue = rootValue;
root->m_pLeft=root->m_pRight=null;
if(startPreOrder==endPreOrder){
if(startInOrder==endInOrder && *startPreOrder==*startInOrder)
return root;
else
throw std::exception("Invalid input.");
}
//在中序序列中找到根节点的位置
int* rootInOrder=startInOrder;
while(rootInOrder <= endInOrder && *rootInorder != rootValue)
++ rootInOrder;
//没有检索到根节点的话抛出异常信息
if(rootInOrder == endInOrder && *rootInOrder != rootValue)
throw std::exception("Invalid Input.");
int leftLength= rootInOrder-startInOrder;
int* leftPreOrderEnd=startPreOrder + leftLength;
//存在左子树的话
if(leftLength > 0)
{
//构建左子树
rppt->m_pLeft = ConstructCorre(startPreOrder+1,leftPreOrderEnd,startInOrder,rootInOrder-1);
}
//存在右子树的话
if(leftLength<endPreOrder - startPreOrder)
{
//构建左子树
rppt->m_pRight = ConstructCorre(leftPreOrderEnd + 1,endPreOrder,rootInOrder+1,endInOrder);
}
return root;
}