二叉树的建立和递归遍历、非递归遍历操作

时间:2021-12-24 11:21:22


二叉树是我们平时使用较多的一种数据结构,它是每个节点最多有两个子树的树结构。关于树的概念和性质就不再多介绍,我来对数的建立和一些操作进行总结。

首先我们定义树的数据类型:

typedef struct TREE_NODE
{
char data;
struct TREE_NODE *lchild;
struct TREE_NODE *rchild;
}*tree_node;
树有一个数据域和两个指针域,采用的是链式存储结构;

我们定义一个tree_node t之后我们首先要创建并输入一个树:

tree_node createTree()   //树的建立
{
char ch;
tree_node t;
ch=getchar(); //输入二叉树数据
if(ch=='#') //判断二叉树是否为空
t=NULL;
else
{
t=(tree_node)malloc(sizeof(tree_node)); //二叉树的生成
t->data=ch;
t->lchild=createTree();
t->rchild=createTree();
}
return t;
}
在输入树的过程中,我们需要输入符号来判断这个树的节点到这里是否停止了,所以有一个判断if(ch=='#');

这样我们便建立好一个树了,并且输入了数据,我们对数最基本也是重要的操作当然就是遍历,对于树的遍历我们有三种方式,分别是前序遍历,中序遍历,后序遍历,我们先看看递归遍历的方法:

void preOrder(tree_node t)  //先序遍历
{
if(t)
{
printf("%c",t->data);
preOrder(t->lchild);
preOrder(t->rchild);
}
}

void intOrder(tree_node t)  //中序遍历
{
if(t)
{
intOrder(t->lchild);
printf("%c",t->data);
intOrder(t->rchild);
}
}
void preOrder(tree_node t)  //先序遍历{    if(t)    {        printf("%c",t->data);        preOrder(t->lchild);        preOrder(t->rchild);    }}
这是我们用递归的方式对树进行的遍历,若我们不采用递归的方式,我们如何进行遍历:

void preOrder(tree_node t) //前序遍历
{
stack<tree_node> s;
tree_node p = t;
while(p!=NULL || !s.empty())
{
while(p!=NULL)
{
cout << p->data;
s.push(p);
p = p->lchild;
}
if(!s.empty())
{
p = s.top();
s.pop();
p = p->rchild;
}
}
}
void intOrder(tree_node t) //中序遍历{    stack<tree_node> s;    tree_node p = t;    while(p!= NULL || !s.empty())    {        while(p!=NULL)        {            s.push(p);            p = p->lchild;        }        if(!s.empty())        {            p = s.top();            cout << p->data;            s.pop();            p = p->rchild;        }    }}

typedef struct node1
{
TREE_NODE *btnode;
bool isFirst;
}*BTNode;
void postOrder(tree_node t) //后序遍历
{
stack<BTNode> s;
tree_node p = t;
BTNode q;
while(p!=NULL || !s.empty())
{
while(p!=NULL)
{
BTNode bt = (BTNode)malloc(sizeof(BTNode));
bt->btnode = p;
bt->isFirst = true;
s.push(bt);
p = p->lchild;
}
if(!s.empty())
{
q = s.top();
s.pop();
if(q->isFirst ==true)
{
q->isFirst = false;
s.push(q);
p = q->btnode->rchild;
}
else
{
cout << q->btnode->data;
p = NULL;
}
}
}
}

非递归的的后序遍历比较麻烦,需要我们沿着左子树一直向下搜索,直到没有左子树的时候,我们此时不能出栈访问,我们还需讲右子树入栈,我们把右子树做了相同处理之后,我们才可以出栈访问,这样我们就需要多设置一个标识每个节点第几次到达栈顶,只有第二次到达栈顶的时候我们才可以出栈访问。

完整的代码如下:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<stack>
using namespace std;
typedef struct TREE_NODE
{
char data;
struct TREE_NODE *lchild;
struct TREE_NODE *rchild;
}*tree_node;
typedef struct node1
{
TREE_NODE *btnode;
bool isFirst;
}*BTNode;
tree_node createTree() //树的建立
{
char ch;
tree_node t;
ch=getchar(); //输入二叉树数据
if(ch=='#') //判断二叉树是否为空
t=NULL;
else
{
t=(tree_node)malloc(sizeof(tree_node)); //二叉树的生成
t->data=ch;
t->lchild=createTree();
t->rchild=createTree();
}
return t;
}

void preOrder(tree_node t) //先序遍历
{
if(t)
{
printf("%c",t->data);
preOrder(t->lchild);
preOrder(t->rchild);
}
}
//void preOrder(tree_node t) //先序遍历
//{
// stack<tree_node> s;
// tree_node p = t;
// while(p!=NULL || !s.empty())
// {
// while(p!=NULL)
// {
// cout << p->data;
// s.push(p);
// p = p->lchild;
// }
// if(!s.empty())
// {
// p = s.top();
// s.pop();
// p = p->rchild;
// }
// }
//}
void intOrder(tree_node t) //中序遍历
{
if(t)
{
intOrder(t->lchild);
printf("%c",t->data);
intOrder(t->rchild);
}
}
//void intOrder(tree_node t) //中序遍历
//{
// stack<tree_node> s;
// tree_node p = t;
// while(p!= NULL || !s.empty())
// {
// while(p!=NULL)
// {
// s.push(p);
// p = p->lchild;
// }
// if(!s.empty())
// {
// p = s.top();
// cout << p->data;
// s.pop();
// p = p->rchild;
// }
// }
//}
void postOrder(tree_node t) //后序遍历
{
if(t)
{
postOrder(t->lchild);
postOrder(t->rchild);
printf("%c",t->data);
}
}
//void postOrder(tree_node t) //后序遍历
//{
// stack<BTNode> s;
// tree_node p = t;
// BTNode q;
// while(p!=NULL || !s.empty())
// {
// while(p!=NULL)
// {
// BTNode bt = (BTNode)malloc(sizeof(BTNode));
// bt->btnode = p;
// bt->isFirst = true;
// s.push(bt);
// p = p->lchild;
// }
// if(!s.empty())
// {
// q = s.top();
// s.pop();
// if(q->isFirst ==true)
// {
// q->isFirst = false;
// s.push(q);
// p = q->btnode->rchild;
// }
// else
// {
// cout << q->btnode->data;
// p = NULL;
// }
// }
// }
//}
int main()
{
int num[10]= {0};
int height;
int i,a=0;
tree_node t;
t=createTree();
printf("前序遍历:");
preOrder(t) ;
printf("\n");
printf("中序遍历:");
intOrder(t);
printf("\n");
printf("后序遍历:");
postOrder(t);
printf("\n");
}