剑指offer-二叉树

【04 重建二叉树】

题目描述

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

思路:

1) 二叉树的构建,赋值,左右子树的便利?
2) 由前序列表,中序列表 恢复左右子树:  前序的根,在中序中划分左右子树,递归重构左右子树
3) C++ 读取未知长度的数组,以回车判断数组结束

样例:

1 2 4 7 3 5 6 8
4 7 2 1 5 3 8 6

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

TreeNode* reConstructBinaryTree(vector pre,vector vin) {	
//根据前序列表和中序列表,重构二叉树。前序的第一个元素为树的根 可以在中序列表划分出 左右子树 
    if(pre.empty()||vin.empty())
		return NULL;
	if(pre.size()!=vin.size())
		return NULL;
		
	TreeNode *p;
 	p = (TreeNode*)malloc(sizeof(TreeNode));
    int i=0,mid=0;
    for(i=0;i pre_left,pre_right,vin_left,vin_right;
	for(i=0;ival = pre[0];
    p->left = reConstructBinaryTree(pre_left,vin_left);
    p->right = reConstructBinaryTree(pre_right,vin_right);
	return p;
}

【17 树的子结构】

题目描述

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

思路:

1) 首先判断,递归判断A和B是否是同一棵树;否则判断左子树或右子树 与 B是否为同一棵树
2) 递归判断 两棵树是否为同一颗树:判断 的各个节点是否都相同


bool SameTree(TreeNode* pRoot1, TreeNode* pRoot2)    // 递归判断 两棵树的元素是否都相同 
{
	bool val;
	if(pRoot2==NULL)
		return true;
	if(pRoot1==NULL)
		return false;
	if(pRoot1->val!=pRoot2->val)
		return false;
	else
		return SameTree(pRoot1->left,pRoot2->left) && SameTree(pRoot1->right,pRoot2->right);
}
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)  // 递归判断	二叉树 2 是不是二叉树1 的子结构
{
	bool val = false;
	if(pRoot1==NULL ||pRoot2==NULL)
		return val;
	return SameTree(pRoot1,pRoot2) | HasSubtree(pRoot1->left,pRoot2) || HasSubtree(pRoot1->right,pRoot2);
}

【18 二叉树的镜像】

题目描述

操作给定的二叉树,将其变换为源二叉树的镜像。

输入描述:

二叉树的镜像定义:源二叉树 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	镜像二叉树
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5

思路:

1) 递归翻转 左右子树
2)非递归翻转, 利用堆存放在 节点

void Mirror(TreeNode *pRoot)		//递归实现 翻转 二叉树 
{
	TreeNode *p; 
	if(pRoot==NULL)
	{
		return;
	}
	else{
		p= pRoot->left;
		pRoot->left = pRoot->right;
		pRoot->right = p;
		Mirror(pRoot->left);
		Mirror(pRoot->right);
		//cout<left->val<<','<right->val< s;			//栈 用来保存 节点。我们还需要翻转左右子树 
	s.push(pRoot);
	while(!s.empty())
	{
		TreeNode *p = s.top();				
		cout<val<left; 
		p->left = p->right;
		p->right = tmp;
		if(p->left!=NULL)
		{
			s.push(p->left);
			cout<val<<"left:"<left->val<right!=NULL){
			s.push(p->right);
			cout<val<<"right:"<right->val<

【22 从上到下打印二叉树】

题目描述

从上往下打印出二叉树的每个节点,同层节点从左至右打印。

思路:

1) 借助队列 存储 节点

vector PrintFromTopToBottom(TreeNode* root) {  //层次遍历  借助 队列
	queue q;
	vector result;
	if(root)
		q.push(root);
	while(!q.empty())
	{
		TreeNode* cur = q.front();
		q.pop();
		result.push_back(cur->val);
		if(cur->left)
		{
			q.push(cur->left);
		}
			
		if(cur->right)
		{
			q.push(cur->right);
		}
	}
	return result;
}

【23 二叉树的后序遍历】 

题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

bool VerifySquenceOfBST(vector s) {
	if(s.size()==1)   
		return true;
	if(s.size()==0)   		//本题 认定,[] 为非二叉搜索树的后序遍历列表 
		return false;
	int mid=0,end = s.size()-1, i=0;
	while(mid left,right;
	for(i=0;i

 

你可能感兴趣的:(剑指Offer)