二叉树是我们平时使用较多的一种数据结构,它是每个节点最多有两个子树的树结构。关于树的概念和性质就不再多介绍,我来对数的建立和一些操作进行总结。
首先我们定义树的数据类型:
typedef struct TREE_NODE树有一个数据域和两个指针域,采用的是链式存储结构;
{
char data;
struct TREE_NODE *lchild;
struct TREE_NODE *rchild;
}*tree_node;
我们定义一个tree_node t之后我们首先要创建并输入一个树:
tree_node createTree() //树的建立在输入树的过程中,我们需要输入符号来判断这个树的节点到这里是否停止了,所以有一个判断if(ch=='#');
{
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 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");
}