数据结构_二叉树
2015-10-21 13:39
417 查看
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stack>
using namespace std;
#define OK 1
#define OVERFLOW -2
typedef int Status;
typedef struct bitnode //二叉树的存储结构
{
char data;
struct bitnode *lchild,*rchild;
}bitnode,*bitree;
//队列的相关操作
typedef struct Tqueue //构造队列
{
bitree qdata;
struct Tqueue *next;
}Tqueue,*ptqueue;
typedef struct
{
ptqueue front; //队头
ptqueue rear; //队尾
}Tlinkqueue;
Status initTqueue(Tlinkqueue &Q) //初始化队列
{
Q.front=Q.rear=(ptqueue)malloc(sizeof(Tqueue));
if(!Q.front)
return OVERFLOW;
Q.front->next=NULL;
return OK;
}
Status deletetqueue(Tlinkqueue &Q) //释放队列
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return OK;
}
Status entqueue(Tlinkqueue &Q,bitree ch) //入队列
{
ptqueue p;
p=(ptqueue)malloc(sizeof(Tqueue));
if(!p)
return OVERFLOW;
p->qdata=ch;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
Status detqueue(Tlinkqueue &Q,bitree ch) //出队列
{
ptqueue p;
if(Q.front==Q.rear)
return OVERFLOW;
p=Q.front->next;
ch=p->qdata;
//data=ch->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
//printf("%c ",data);
return OK;
}
Status is_qempty(Tlinkqueue &Q) //判断队列是否为空
{
if(Q.front==Q.rear)
return 1;
else
return 0;
}
//栈的相关操作
typedef struct Tstack //构造栈
{
bitree *base;
bitree *top;
int stacksize;
}Tstack;
Status initTstack(Tstack &s) //初始化栈
{
s.base=(bitree*)malloc(105*sizeof(bitree));
if(!s.base)
return OVERFLOW;
s.top=s.base;
s.stacksize=105;
return OK;
}
Status gettop(Tstack &s,bitree &ch) //访问栈顶
{
if(s.base==s.top)
return OVERFLOW;
ch=*(s.top-1);
return OK;
}
Status push(Tstack &s,bitree ch) //入栈
{
if(s.top-s.base>=s.stacksize)
{
s.base=(bitree *)realloc(s.base,(s.stacksize+15)*sizeof(bitree));
if(!s.base)
return OVERFLOW;
s.top=s.base+s.stacksize;
s.stacksize+=15;
}
*s.top++=ch;
return OK;
}
Status pop(Tstack &s,bitree &ch) //删除栈顶
{
if(s.top==s.base)
return OVERFLOW;
ch=*--s.top;
return OK;
}
Status is_sempty(Tstack &s) //判断栈是否为空
{
if(s.base==s.top)
return 1;
else
return 0;
}
void print(bitree &T) //输出函数
{
if (T->data!='#')
printf("%c ",T->data);
}
void XXtraverse(bitree &T) //先序遍历非递归
{
Tstack s;
initTstack(s);
bitree p;
p=T;
bitree t1,t2;
while(p!=NULL||!is_sempty(s))
{
if(p!=NULL)
{
push(s,p);
printf("%c ",p->data);
p = p->lchild;
}
else
{
gettop(s,t1);
p=t1;
pop(s,t2);
p = p->rchild;
}
}
}
void ZZtraverse(bitree &T) //中序遍历非递归
{
Tstack s;
initTstack(s);
bitree p=T;
bitree t1,t2;
while(p!=NULL||!is_sempty(s))
{
if(p!=NULL)
{
push(s,p);
p = p->lchild;
}
else
{
gettop(s,t1);
p=t1;
pop(s,t2);
printf("%c ",p->data);
p = p->rchild;
}
}
}
/*void HHtraverse(bitree T) //后序遍历非递归
{
Tstack s;
initTstack(s);
bitree cur,t1,t2;
bitree pre=NULL;
push(s,*T);
while(!is_sempty(s))
{
gettop(s,t1);
cur=t1;
if((cur->lchild==NULL&&cur->rchild==NULL)||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
{
printf("%c ",cur->data);
pop(s,t2);
pre=cur;
}
else
{
if(cur->rchild!=NULL)
push(s,*cur->rchild);
if(cur->lchild!=NULL)
push(s,*cur->lchild);
}
}
}*/
void HHtraverse(bitree &T)
{
bitree cur=T;
bitree pre=NULL;
Tstack s;
initTstack(s);
while(cur!=NULL||!is_sempty(s))
{
while(cur!=NULL)
{
push(s,cur);
cur=cur->lchild;
}
gettop(s,cur);
if(cur->rchild==NULL||cur->rchild==pre) //ABC##DE#G##F###
{
printf("%c ",cur->data);
//cout<<cur->data<<" ";
pre=cur;
pop(s,cur);
cur=NULL;
}
else cur=cur->rchild;
}
}
/*void HHtraverse(bitree T) //后序遍历非递归
{
Tstack s;
initTstack(s);
bitree p=T;
bitree t1,t2,t3;
t2=NULL;
while(p!=NULL||!is_sempty(s))
{
while(p!=NULL)
{
push(s,*p);
p = p->lchild;
}
gettop(s,t1);
p=t1;
if(p->rchild == NULL || p->rchild == t2)
{
printf("%c ",p->data);
t2=p;
pop(s,t3);
p=NULL;
}
else
p=p->rchild;
}
}*/
/*void HHtraverse(bitree T) // 后序遍历的非递归
{
stack<bitree> S;
bitree curr = T ; // 指向当前要检查的节点
bitree previsited = NULL; // 指向前一个被访问的节点
while(curr != NULL || !S.empty()) // 栈空时结束
{
while(curr != NULL) // 一直向左走直到为空
{
S.push(curr);
curr = curr->lchild;
}
curr = S.top();
// 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
if(curr->rchild == NULL || curr->rchild == previsited)
{
cout<<curr->data<<" ";
previsited = curr;
S.pop();
curr = NULL;
}
else
curr = curr->rchild; // 否则访问右孩子
}
}*/
void ZCtraverse(bitree &T) //层次遍历
{
bitree p,t1;
p=T;
Tlinkqueue Q;
initTqueue(Q);
entqueue(Q,p);
while(!is_qempty(Q))//ABC##DE#G##F###
{
p = Q.front->next->qdata;
printf("%c ",p->data);
detqueue(Q,t1);
if(p->lchild != NULL)
{
entqueue(Q,p->lchild);
}
if(p->rchild != NULL)
{
entqueue(Q,p->rchild);
}
}
}
Status createbitree(bitree &T) //创建二叉树
{
char ch;
scanf("%c",&ch);
if (ch=='#') T=NULL;
else
{
if (!(T=(bitree)malloc(sizeof(bitnode))))
return OVERFLOW;
T->data=ch;
createbitree(T->lchild);
createbitree(T->rchild);
}
return OK;
}
void Xtraverse(bitree &T) //先序遍历(递归)
{
if (T!=NULL)
{
print(T);
Xtraverse(T->lchild);
Xtraverse(T->rchild);
}
}
void Ztraverse(bitree &T) //中序遍历(递归)
{
if (T!=NULL)
{
Ztraverse(T->lchild);
print(T);
Ztraverse(T->rchild);
}
}
void Htraverse(bitree &T) //后序遍历(递归)
{
if (T!=NULL)
{
Htraverse(T->lchild);
Htraverse(T->rchild);
print(T);
}
}
Status max(int a,int b) //比较函数
{
return a>b?a:b;
}
Status get_high(bitree &T) //返回树高
{
if(T==NULL)
return 0;
return max(get_high(T->lchild),get_high(T->rchild))+1;
}
Status get_leaf(bitree &T) //返回叶子数
{
if(T==NULL)
return 0;
else if(T->rchild==NULL && T->rchild==NULL)
return 1;
else
return get_leaf(T->lchild)+get_leaf(T->rchild);
}
Status get_totalnode(bitree &T) //返回树的结点数
{
if(T==NULL)
return 0;
return get_totalnode(T->lchild)+get_totalnode(T->rchild)+1;
}
int main()
{
bitree T;
createbitree(T);
printf("树高=%d\n",get_high(T));
printf("叶子数=%d\n",get_leaf(T));
printf("结点数=%d\n",get_totalnode(T));
printf("先序遍历:");
Xtraverse(T);
printf("\n");
printf(" 非递归:");
XXtraverse(T);
printf("\n");
printf("中序遍历:");
Ztraverse(T);
printf("\n");
printf(" 非递归:");
ZZtraverse(T);
printf("\n");
printf("后序遍历:");
Htraverse(T);
printf("\n");
printf(" 非递归:");
HHtraverse(T);
printf("\n");
printf("层次遍历:");
ZCtraverse(T);
printf("\n");
free(T);
return 0;
}