C/C++学习笔记(三)

读书感悟:最近在看何海涛的《剑指Offer》一书,因为以前在学习数据结构的时候,二叉树编程学习的不是很好,经常拿到二叉树的问题,束手无策,这次经过思考,成功解决,算是小小的进步!

1、重建二叉树

题目:输入某二叉树的前序遍历和中序遍历结果,请重建该二叉树,假设输入的前序遍历和中序遍历的结果不含重复数字,例如输入的前序遍历序列{1,2,4,7,3,5,6,8} 和中序遍历序列{4,7,2,1,5,3,8,6}。

struct BinaryTreeNode
{
   int value;
   BinaryTreeNode* left;
   BinaryTreeNode* right;
}

思路:在前序序列中,第一个值为1,则此为根节点,再在中序序列中找到1,以此为分界,前面的4,7,2便为左子树的节点,后面的5,3,8,6则为右子树的节点,采用递归的方法,左子树和右子树的建立又转化为与题目类似的问题。
现在我们要写的函数为,输入:前序遍历序列和中序遍历序列。返回:根节点指针。

我们经常不能理清递归过程,最主要的原因是没有很清楚的抓住递归的输入和返回值。如果我们在编程时,很清楚的理清递归函数的输入和返回,往往能很快的想清楚递归并解决问题。

在理清思路后,代码就不难写出了。递归代码如下:

BinaryTreeNode* Construct(int* preorder,int*                inorder,int length)  //preorder指向前序序列,inorder指向中序序列                   
                     //lenhth为节点个数
{
  if(length<=0 || preorder==null || inorder==null)
     retrun null;      //判断是否为空

  int* endPreorder;
  int* endInorder;

 return ConstructCore(preorder,endPreorder,inorder,endInorder);
}


BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder)
{

  int rootValue;
  BinaryTreeNode* root=new BinaryTreeNode();
  root->value=*startPreorder;
  rootValue=*startPreorder;
  root->left=null;
  root->right=null;

  if(startPreorder==endPreorder)  //当两种序列的长度为1时
  {
     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* leftEndPreorder=startPreorder+leftLength;

if(leftLength>0)
{
   root->left
 =ConstructCore(startPreorder+1,leftEndPreorder,startInorder,rootInorder-1);
}

if(length<endPreorder-startPreorder)
{
   root->right
 =ConstructCore(letfEndPreorder+1,endPreorder,rootInorder+1,endInorder);
}

return root;  
}

2、 编程时遇到的小知识

在编程时,遇到int型指针的指向问题。
int a[]={1,2,3,4};
*(a+1)=2;
因为这里的指针是与数据类型相关的,在指针+1,其地址自动+4,指向数组下一个坐标。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值