#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;
}