Merge Two Binary Trees
Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not.
You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree.
Example 1:
Input:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
Output:
Merged tree:
3
/ \
4 5
/ \ \
5 4 7
Note: The merging process must start from the root nodes of both trees.
实现程序:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (!t1) return t2;
if (!t2) return t1;
TreeNode* node = new TreeNode(t1->val + t2->val);
node->left = mergeTrees(t1->left, t2->left);
node->right = mergeTrees(t1->right, t2->right);
return node;
}
};
c++程序:
//#include<iostream>
//using namespace std;
//
//struct TreeNode {
// int val;
// TreeNode *left;
// TreeNode *right;
// TreeNode(int x) : val(x), left(NULL), right(NULL) {}
// };//结构体声明,
//
//class Solution {
//public:
// TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
// if (!t1) return t2;
// if (!t2) return t1;
//
// TreeNode* node = new TreeNode(t1->val + t2->val);
// node->left = mergeTrees(t1->left, t2->left);
// node->right = mergeTrees(t1->right, t2->right);
// cout << node << endl;
// return node;
// }
//};
biTree.cpp : 定义控制台应用程序的入口点。
#include <iostream>
using namespace std;
//*************************************************************************************
//二叉树结点类的定义
//二叉树结点类的定义
template<class T> //模版结构体
struct TreeNode
{
T data;
TreeNode <T> *Lchild, *Rchild; //节点的左子树和右子树
//可选择参数的默认构造函数
/*TreeNode(T nodeValue = T(),TreeNode<T> *leftNode = NULL,TreeNode<T> *rightNode = NULL )
:data(nodeValue),Lchild(leftNode),Rchild(rightNode){} */
};
//**************************************************************************************
//二叉树的建立
template <class T> //模版方法,声明一个模板,虚拟类型名为T(数据类型),尖括号中是模板的参数列表,关键字class后面是类型参数,后面没有分号
void createBinaryTree(TreeNode<T> *&root) //传递指针的引用
{
TreeNode<T>* p = root;//指向T类对象的指针
T nodeValue;
cin >> nodeValue;
if (nodeValue == -1)
{
root = NULL;
}
else
{
root = new TreeNode<T>(); //构造一个节点
root->data = nodeValue;
createBinaryTree(root->Lchild); //递归构造左子树(*p).Lchild,即root所指向的对象中的成员或函数
createBinaryTree(root->Rchild); //递归构造右子树
}
}
//************************************************************************************
//二叉树的先序遍历
template <class T>
void preOrder(TreeNode<T> * & p) //传递指针的引用
{
if (p)
{
cout << p->data << " ";
preOrder(p->Lchild);
preOrder(p->Rchild);
}
}
//**************************************************************************************
//二叉树的中序遍历
template <class T>
void inOrder(TreeNode<T> * & p) //传递指针的引用
{
if (p)
{
inOrder(p->Lchild);
cout << p->data << " ";
inOrder(p->Rchild);
}
}
//**************************************************************************************
//二叉树的后序遍历
template <class T>
void postOrder(TreeNode<T> *& p) //传递指针的引用
{
if (p)
{
postOrder(p->Lchild);
postOrder(p->Rchild);
cout << p->data << " ";
}
}
//*************************************************************************************
//统计二叉树中结点的个数
template<class T>
int countNode(TreeNode<T> * & p) //传递指针的引用
{
if (p == NULL) return 0;
return 1 + countNode(p->Lchild) + countNode(p->Rchild);
}
//***********************************************************************************
//求二叉树的深度
template<class T>
int depth(TreeNode<T> *& p) //传递指针的引用
{
if (p == NULL)
return -1;
int h1 = depth(p->Lchild);
int h2 = depth(p->Rchild);
if (h1>h2)return (h1 + 1);
return h2 + 1;
}
//***********************************************************************************
//二叉树的消毁操作
//容易混淆的错误声明:void destroy(TreeNode<T>* p) 这种声明会创建一个局部的临时对象来保存传递的指针
//虽然2个指针都执行同一块堆空间,delete局部指针 也会删除二叉树结构所占用的堆内存
//但是全局传递的那个指针将会是垃圾指针,会产生不可预料的错误
//void destroy(TreeNode<T> *& p) 此函数的参数为全局指针的一个别名,代表全局指针rootNode本身
// 这样p = NULL;能达到置空指针的左右
//可选的方案是在调用完destroy方法之后,在主函数中执行rootNode = NULL操作
template<class T>
void destroy(TreeNode<T> *& p) //传递指针的引用,消毁函数,用来消毁二叉树中的各个结点
{
if (p)
{
//错误 return之后 没有执行delete p
//return destroy(p->Lchild);
//return destroy(p->Rchild);
destroy(p->Lchild);
destroy(p->Rchild);
//delete只能释放由用户通过new方式在堆中申请的内存,
//是通过变量声明的方式由系统所声明的栈内存不能使用delete删除
//delete和free函数一样,不修改它参数对应指针指向的内容,也不修改指针本身,
//只是在堆内存管理结构中将指针指向的内容标记为可被重新分配
delete p;
//堆上内存释放 栈上指针并不销毁
//此时p指向的地址未知,此时执行*p = ? 操作会导致不可预料的错误
//但是可以重新赋值p = &x;
//最好delete之后把P置空
p = NULL;
}
}
template<class T>
TreeNode<T> *&mergeTrees(TreeNode<T> *&root1, TreeNode<T> *&root2, TreeNode<T> *&root3) //传递指针的引用2 1 -1 4 -1 -1 3 -1 7 -1 -1
{
// if (!t1) return t2;
// if (!t2) return t1;
//
// TreeNode* node = new TreeNode(t1->val + t2->val);
// node->left = mergeTrees(t1->left, t2->left);
// node->right = mergeTrees(t1->right, t2->right);
// cout << node << endl;
// return node;
TreeNode<T>* p = root3;//指向T类对象的指针
root3 = new TreeNode<T>();
if (!root1&&root2) { root3->data = root2->data; cout << root3->data << endl; return root3; }
else if (!root2&&root1)
{
root3->data = root1->data; cout << root3->data << endl; return root3;
}
else if (root1&&root2)
{
root3->data = root1->data + root2->data;
}
else { return root3; }
cout << root3->data << endl;
mergeTrees(root1->Lchild, root2->Lchild, root3->Lchild);
mergeTrees(root1->Rchild, root2->Rchild, root3->Rchild); //递归构造右子树1 3 5 -1 -1 -1 2 -1 -1
return root3;
}
//********************************************************************************
//主函数的设计
int main()
{
TreeNode<int> * rootNode = NULL;
TreeNode<int> * rootNode1 = NULL;
TreeNode<int> * rootNode2 = NULL;
int choiced = 0;
while (true)
{
system("cls"); //清屏
cout << "\n\n\n ---主界面---\n\n\n";
cout << " 1、创建二叉树 2、先序遍历二叉树\n";
cout << " 3、中序遍历二叉树 4、后序遍历二叉树\n";
cout << " 5、统计结点总数 6、查看树深度 \n";
cout << " 7、消毁二叉树 0、退出合并二叉树\n\n";
cout << " 请选择操作:";
cin >> choiced;
if (choiced == 0)
{
cout << "请输入每个结点,回车确认,并以-1结束:\n";
createBinaryTree(rootNode);
cout << "请输入每个结点,回车确认,并以-1结束:\n";
createBinaryTree(rootNode1);
rootNode2 = mergeTrees(rootNode, rootNode1, rootNode2);
}
else if (choiced == 1)
{
system("cls");
cout << "请输入每个结点,回车确认,并以-1结束:\n";
createBinaryTree(rootNode);
}
else if (choiced == 2)
{
system("cls");
cout << "先序遍历二叉树结果:\n";
preOrder(rootNode);
cout << endl;
system("pause"); //暂停屏幕
}
else if (choiced == 3)
{
system("cls");
cout << "中序遍历二叉树结果:\n";
inOrder(rootNode);
cout << endl;
system("pause");
}
else if (choiced == 4)
{
system("cls");
cout << "后序遍历二叉树结果:\n";
postOrder(rootNode);
cout << endl;
system("pause");
}
else if (choiced == 5)
{
system("cls");
int count = countNode(rootNode);
cout << "二叉树中结点总数为" << count << endl;
system("pause");
}
else if (choiced == 6)
{
system("cls");
int dep = depth(rootNode);
cout << "此二叉树的深度为" << dep << endl;
system("pause");
}
else if (choiced == 7)
{
system("cls");
cout << "二叉树已被消毁!\n";
destroy(rootNode);
cout << endl;
system("pause");
}
else
{
system("cls");
cout << "\n\n\n\n\n\t错误选择!\n";
}
}
}
现有问题:
1、学习了类内指针的使用和调用方法
2、在两个二叉树不是完全二叉树时,会出现不对应的节点值无法相加问题,导致程序中断,更改之前的返回类型之后改善错误。希望有大神帮助解答。