数据结构之二叉树


在二叉树中每个节点最多只能有两个子节点。即左子节点和有子节点。
 在二叉树中最重要的操作应当是遍历。即按照某一顺序访问二叉树中的每一个节点。
 一般有如下几种遍历方法
 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;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值