您的位置:首页 > 编程语言 > C语言/C++

C++二叉树遍历总结\100. Same Tree

2017-02-15 14:45 218 查看
理论学习
概念介绍

遍历图解

遍历算法

代码实践
实现模板

Same Tree
题目描述

代码实现

转载请注明出处:http://blog.csdn.net/c602273091/article/details/55195284

理论学习

概念介绍

二叉树的遍历分成前序、中序、后序遍历。

前序就是访问结点的操作发生在遍历其左右子树之前。

中序就是访问结点的操作发生在遍历其左右子树之中,一般是遍历左边子树以后。

后序就是访问结点的操作发生在遍历其左右子树之后。

这里可以参考【1】中,对数据结构做了一个整理。

遍历图解



图中每个节点经过了3次。

先序为: A B D C E F

中序为: D B A E C F

后序为: D B E F C A

PS:(1) 在搜索路线中,若访问结点均是第一次经过结点时进行的,则是前序遍历;若访问结点均是在第二次(或第三次)经过结点时进行的,则是中序遍历(或后序遍历)。只要将搜索路线上所有在第一次、第二次和第三次经过的结点分别列表,即可分别得到该二叉树的前序序列、中序序列和后序序列。

  (2) 上述三种序列都是线性序列,有且仅有一个开始结点和一个终端结点,其余结点都有且仅有一个前趋结点和一个后继结点。为了区别于树形结构中前趋(即双亲)结点和后继(即孩子)结点的概念,对上述三种线性序列,要在某结点的前趋和后继之前冠以其遍历次序名称。上图所示的二叉树中结点C,其前序前趋结点是D,前序后继结点是E;中序前趋结点是E,中序后继结点是F;后序前趋结点是F,后序后继结点是A。但是就该树的逻辑结构而言,C的前趋结点是A,后继结点是E和F。

二叉树建立过程可以看:【2】

// 假设虚结点输入时以空格字符表示,相应的构造算法为:
void CreateBinTree (BinTree *T) {
//构造二叉链表。T是指向根指针的指针,故修改*T就修改了实参(根指针)本身
char ch;
if((ch=getchar())=='') *T=NULL; //读人空格,将相应指针置空
else{ //读人非空格
*T=(BinTNode *)malloc(sizeof(BinTNode)); //生成结点
(*T)->data=ch;
CreateBinTree(&(*T)->lchild); //构造左子树
CreateBinTree(&(*T)->rchild); //构造右子树
}
}


遍历算法

1.中序遍历的递归算法定义:若二叉树非空,则依次执行如下操作:

(1)遍历左子树;

(2)访问根结点;

(3)遍历右子树。

2.先序遍历的递归算法定义:若二叉树非空,则依次执行如下操作:

(1) 访问根结点;

(2) 遍历左子树;

(3) 遍历右子树。

3.后序遍历得递归算法定义:若二叉树非空,则依次执行如下操作:

(1)遍历左子树;

(2)遍历右子树;

(3)访问根结点。

对于这个详细的图解,可以看【8】。

代码实践

参考【3】【4】中的代码建立二叉树。

实现模板

在【5】里,作者总结了一套很好的二叉树遍历的模板。以下为摘录部分。

前序遍历:

//前序遍历
void preorder(TreeNode *root, vector<int> &path)
{
if(root != NULL)
{
path.push_back(root->val);
preorder(root->left, path);
preorder(root->right, path);
}
}


中序遍历:

//中序遍历
void inorder(TreeNode *root, vector<int> &path)
{
if(root != NULL)
{
inorder(root->left, path);
path.push_back(root->val);
inorder(root->right, path);
}
}


后序遍历:

//后续遍历
void postorder(TreeNode *root, vector<int> &path)
{
if(root != NULL)
{
postorder(root->left, path);
postorder(root->right, path);
path.push_back(root->val);
}
}


非递归的前序:

//非递归前序遍历
void preorderTraversal(TreeNode *root, vector<int> &path)
{
stack<TreeNode *> s;
TreeNode *p = root;
while(p != NULL || !s.empty())
{
while(p != NULL)
{
path.push_back(p->val);
s.push(p);
p = p->left;
}
if(!s.empty())
{
p = s.top();
s.pop();
p = p->right;
}
}
}


非递归的中序:

//非递归中序遍历
void inorderTraversal(TreeNode *root, vector<int> &path)
{
stack<TreeNode *> s;
TreeNode *p = root;
while(p != NULL || !s.empty())
{
while(p != NULL)
{
s.push(p);
p = p->left;
}
if(!s.empty())
{
p = s.top();
path.push_back(p->val);
s.pop();
p = p->right;
}
}
}


非递归的后序:

//非递归后序遍历-迭代
void postorderTraversal(TreeNode *root, vector<int> &path)
{
stack<TempNode *> s;
TreeNode *p = root;
TempNode *temp;
while(p != NULL || !s.empty())
{
while(p != NULL) //沿左子树一直往下搜索,直至出现没有左子树的结点
{
TreeNode *tempNode = new TreeNode;
tempNode->btnode = p;
tempNode->isFirst = true;
s.push(tempNode);
p = p->left;
}
if(!s.empty())
{
temp = s.top();
s.pop();
if(temp->isFirst == true)   //表示是第一次出现在栈顶
{
temp->isFirst = false;
s.push(temp);
p = temp->btnode->right;
}
else  //第二次出现在栈顶
{
path.push_back(temp->btnode->val);
p = NULL;
}
}
}
}


在【5】中,作者提出了更加简单的二叉树实现,推荐看看。

在【6】中,作者提出了二叉树先中后序遍历(递归&非递归)算法、层次遍历(正序&逆序&锯齿形)非递归算法、二叉树深度算法、结点总数算法。

还有一些应用,比如搜索:二叉树的查找【7】

bintree search_tree(bintree t,datatype x){
if(!t){
return NULL;
}
if(t->data == x){
return t;
}else{
if(!search_tree(t->lchild,x)){
return search_tree(t->rchild,x);
}
return t;
}
}


统计节点的个数:

int count_tree(bintree t){
if(t){
return (count_tree(t->lchild)+count_tree(t->rchild)+1);
}
return 0;
}


比较两个数是否相同:

int is_equal(bintree t1,bintree t2){
if(!t1 && !t2){      //都为空就相等
return 1;
}
if(t1 && t2 && t1->data == t2->data){      //有一个为空或数据不同就不判断了
if(is_equal(t1->lchild,t2->lchild))
if(is_equal(t1->rchild,t2->rchild)){
return 1;
}
}
return 0;
}


100. Same Tree

题目描述

Given two binary trees, write a function to check if they are equal or not.

Two binary trees are considered equal if they are structurally identical and the nodes have the same value.


代码实现

/**
* 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:
bool isSameTree(TreeNode* t1, TreeNode* t2) {
if(!t1 && !t2){      //都为空就相等
return true;
}
if(t1 && t2 && t1->val == t2->val){      //有一个为空或数据不同就不判断了
if(isSameTree(t1->left,t2->left))
if(isSameTree(t1->right,t2->right)){
return true;
}
}
return false;
}
};


【1】数据结构整理:http://student.zjzk.cn/course_ware/data_structure/web/shu/shu6.3.1.htm

【2】二叉树建立动画过程:http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/erchashujianli.htm

【3】建立二叉树:http://blog.csdn.net/pony_maggie/article/details/38390513

【4】二叉树的三种遍历方法:http://blog.csdn.net/presidentpresident/article/details/7549170

【5】二叉树各种方法总结:http://www.jianshu.com/p/49c8cfd07410

【6】二叉树各种遍历方法:http://www.cnblogs.com/yfsmooth/p/4671903.html

【7】二叉树的很多应用:http://blog.csdn.net/fansongy/article/details/6798278/

【8】二叉树详细图解:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/27/1766233.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息