本篇文章主要涉及到
- 二叉树的非递归遍历(ForwardTravesal()/MiddleTravesal())
- 二叉树的深度: DepthOfTree()
- 二叉树的叶子节点个数: CountsOfLeaves()
二叉树的非递归需要借助栈,原因在于递归遍历思想是基于栈的,现在要变为非递归,需要借助额外空间,空间换时间。
- 关于二叉树的递归遍历(RecursiveTravesal)见博文
Python实现二叉树遍历
- 前序遍历ForwardTravesal()—–根左右:
1.当前节点p,访问p->data将p存入Stack中
2.若p->left存在,将p->left作为当前的p;若不存在,将栈顶元素出栈,再将p->right作为当前的p
3.栈空即为结束
void NonRecursiveForward(BiTree root)
{
BiTree p = root;
int depth = DepthOfTree(root);
BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);
int top = -1;
while(p != NULL || top != -1)
{
while(p != NULL)
{
cout<<p->data<<" ";
stack[++top] = p;
p = p->left;
}
if(top != -1)
{
p = stack[top--];
p = p->right;
}
}
cout<<endl;
}
- 中序遍历MiddleTravesal()—–左根右
注:中序遍历与前序遍历输出时机不同,相信大家秒懂。
void NonRecursiveMiddle(BiTree root)
{
BiTree p = root;
int depth = DepthOfTree(root);
BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);
int top = -1;
while(p != NULL || top != -1)
{
while(p != NULL)
{
stack[++top] = p;
p = p->left;
}
if(top != -1)
{
p = stack[top--];
cout<<p->data<<" ";
p = p->right;
}
}
cout<<endl;
}
二叉树的深度,可以采用递归来解决,通俗易懂。
树的深度等于当前节点深度 = 1 + 子树(左子树和右子树最大深度)深度
/**
* get depth of tree
*/
int DepthOfTree(BiTree root)
{
int deep = 0;
if (root)
{
int leftDepth = DepthOfTree(root->left);
int rightDepth = DepthOfTree(root->right);
deep = leftDepth >= rightDepth ? leftDepth+1 : rightDepth+1;
}
return deep;
}
二叉树叶子节点个数等价于
满足left == NULL && right == NULL的节点
同理,知道叶子节点个数就会知道度为2的节点个数
/**
* get counts of leaves
*/
int CountsOfLeaves(BiTree root)
{
//int count = 0;
if (!root)
return 0;
if (root->left == NULL && root->right == NULL)
{
return 1;
}
int lc = CountsOfLeaves(root->left);
int rc = CountsOfLeaves(root->right);
return (lc+rc);
}
二叉树按层遍历TravesalByLayer(),同样需要借助额外空间
利用队列先进先出的特性,可以实现,爱思考的大家动手吧。
心得
经过一个多月的面试,遇到算法题中二叉树相关的比较多,比如左右子树相交的第一个节点,堆排序的树结构链表实现等。总的来说,树说难不难,说易不易,理解其中的编程思想很重要。
完整代码
#include <iostream>
using namespace std;
typedef int DataType;
typedef struct node
{
DataType data;
struct node *left;
struct node *right;
}BTNode, *BiTree;
int CreateABinaryTree(BiTree *t)
{
// static count = 0;
*t = (BiTree)malloc(sizeof(BTNode));
if (!(*t))
{
/* can't create tree */
exit(-1);
}
DataType dt;
cin>>dt;
if (dt == -1)
{
/* code */
*t = NULL;
}else
{
(*t)->data = dt;
cout<<"You can input data to left (Root is "<<dt<<"): "<<endl;
CreateABinaryTree(&((*t)->left));
cout<<"You can input data to right (Root is "<<dt<<"): "<<endl;
CreateABinaryTree(&((*t)->right));
}
return 1;
}
/**
*
* Traversal with Recursive to BTree
*
*/
void RecursiveRootLeftRight(BiTree root)
{
if (root)
{
/* code */
cout<<root->data<<" ";
RecursiveRootLeftRight(root->left);
RecursiveRootLeftRight(root->right);
}
}
void RecursiveLeftRootRight(BiTree root)
{
if (root)
{
/* code */
RecursiveLeftRootRight(root->left);
cout<<root->data<<" ";
RecursiveLeftRootRight(root->right);
}
}
void RecursiveLeftRightRoot(BiTree root)
{
if (root)
{
/* code */
RecursiveLeftRightRoot(root->left);
RecursiveLeftRightRoot(root->right);
cout<<root->data<<" ";
}
}
/**
* get depth of tree
*/
int DepthOfTree(BiTree root)
{
int deep = 0;
if (root)
{
int leftDepth = DepthOfTree(root->left);
int rightDepth = DepthOfTree(root->right);
deep = leftDepth >= rightDepth ? leftDepth+1 : rightDepth+1;
}
return deep;
}
/**
* get counts of leaves
*/
int CountsOfLeaves(BiTree root)
{
//int count = 0;
if (!root)
return 0;
if (root->left == NULL && root->right == NULL)
{
return 1;
}
int lc = CountsOfLeaves(root->left);
int rc = CountsOfLeaves(root->right);
return (lc+rc);
}
/**
*
* Traversal with Non-Recursive to BTree
*
*/
void NonRecursiveForward(BiTree root)
{
BiTree p = root;
int depth = DepthOfTree(root);
BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);
int top = -1;
while(p != NULL || top != -1)
{
while(p != NULL)
{
cout<<p->data<<" ";
stack[++top] = p;
p = p->left;
}
if(top != -1)
{
p = stack[top--];
p = p->right;
}
}
cout<<endl;
}
void NonRecursiveMiddle(BiTree root)
{
BiTree p = root;
int depth = DepthOfTree(root);
BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);
int top = -1;
while(p != NULL || top != -1)
{
while(p != NULL)
{
stack[++top] = p;
p = p->left;
}
if(top != -1)
{
p = stack[top--];
cout<<p->data<<" ";
p = p->right;
}
}
cout<<endl;
}
int main(int argc, char const *argv[])
{
cout<<"Datasource fo Tree "<<endl;
BiTree root;
/** create a binary tree */
CreateABinaryTree(&root);
cout<<"Binary Tree is created well."<<endl;
cout<<"Depth Of Tree: "<<DepthOfTree(root)<<endl;
cout<<"Counts Of Leaves: "<<CountsOfLeaves(root)<<endl;
/** Forward Traversal */
cout<<"*** Recursive Forward Traversal ***"<<endl;
RecursiveRootLeftRight(root);
cout<<endl;
/** Middle Traversal */
cout<<"*** Recursive Middle Traversal ***"<<endl;
RecursiveLeftRootRight(root);
cout<<endl;
/** Backward Traversal */
cout<<"*** Recursive Backward Traversal ***"<<endl;
RecursiveLeftRightRoot(root);
cout<<endl;
cout<<"*** Non-Recursive Forward Traversal ***"<<endl;
NonRecursiveForward(root);
cout<<"*** Non-Recursive Middle Traversal ***"<<endl;
NonRecursiveMiddle(root);
return 0;
}