樹和二叉樹3——各種遍歷輸出二叉樹
阿新 • • 發佈:2018-12-09
程式碼輸出結果如下:
二叉樹 bt:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))
***層次遍歷序列:A B C D E F G H I J K L M N
先序遍歷序列:
遞迴演算法:A B D E H J K L M N C F G I
非遞迴演算法:A B D E H J K L M N C F G I
中序遍歷序列:
遞迴演算法:D B J H L K M N E A F C G I
非遞迴演算法:D B J H L K M N E A F C G I
後序遍歷序列:
遞迴演算法:D J L N M K H E B F I G C A
***非遞迴演算法:D J L N M K H E B F I G C A
完整原始碼如下:
#include <stdio.h>
#include <stdlib.h>
#include<queue>
using namespace std;
const int maxsize=100;
typedef struct BiTNode{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void LevelOrderTravese(BiTree t)
{
queue <BiTree> bt;
if(t==NULL)
return ;
bt.push(t);
while(!bt.empty())
{
t=bt.front(); bt.pop();
printf("%c ",t->data);
if(t->lchild) bt.push(t->lchild);
if(t->rchild) bt.push(t->rchild);
}
}
//用最簡單的陣列模擬佇列來一遍(當然很浪費空間就是了,可是好理解好實現啊)
void LevelOrderTravese1(BiTree t)
{
BiTree queue[maxsize];//佇列給到和結點數一樣,倒也不用擔心溢位了(空間浪費確實嚴重)
int front=0,back=0;
if(t==NULL)
return;
queue[back++]=t;
while(front!=back)//front==back佇列為空
{
t=queue[front++];
printf("%c ",t->data);
if(t->lchild) queue[back++]=t->lchild;
if(t->rchild) queue[back++]=t->rchild;
}
}
int init(BiTree &t)
{
t=NULL;
return 1;
}
int BiTreedestroy(BiTree &t)
{
if(t)
{
if(t->lchild)
BiTreedestroy(t->lchild);
if(t->rchild)
BiTreedestroy(t->rchild);
free(t);
t=NULL;
}
return 1;
}
void BiTreecreate(BiTree &t)
{
char ch;
char pch[]="ABD$$EHJ$$KL$$M$N$$$CF$$G$I$$";
static int i=0;
ch=pch[i++];
if(ch=='$')
t=NULL;
else
{
t=(BiTree)malloc(sizeof(BiTNode));
if(!t) exit(-1);
t->data=ch;
BiTreecreate(t->lchild);
BiTreecreate(t->rchild);
}
}
int flag=1;
void pre_order_traveral_brackets1(BiTree t)
{
if(t)
{
printf("%c",t->data);
if(t->lchild||t->rchild)
{
printf("(");flag++;
}
pre_order_traveral_brackets1(t->lchild);
if(t->rchild)
printf(",");
pre_order_traveral_brackets1(t->rchild);
}
}
void pre_order_traveral_brackets(BiTree t)
{
if(t)
{
printf("%c",t->data);
printf("(");
pre_order_traveral_brackets1(t->lchild);
while(--flag)
{
printf(")");
}
printf(",");
pre_order_traveral_brackets1(t->rchild);
while(flag--+1)
{
printf(")");
}
}
}
void PreOrderTraverse(BiTree t)
{
if(t)
{
printf("%c ",t->data);
PreOrderTraverse(t->lchild);
PreOrderTraverse(t->rchild);
}
}
void InOrderTraverse(BiTree t)
{
if(t)
{
InOrderTraverse(t->lchild);
printf("%c ",t->data);
InOrderTraverse(t->rchild);
}
}
void PostOrderTraverse(BiTree t)
{
if(t)
{
PostOrderTraverse(t->lchild);
PostOrderTraverse(t->rchild);
printf("%c ",t->data);
}
}
// 先序遍歷非遞迴遍歷演算法
void PreOrderTraverse_NoRecursion(BiTree t)
{
BiTree stack[maxsize];
int top=-1;
while(t||top!=-1)
{
while(t)
{
printf("%c ",t->data);
stack[++top]=t;
t=t->lchild;
}
if(top!=-1)//根結點沒有右孩子時用到
{
t=stack[top--];
t=t->rchild;
}
}
}
// 中序遍歷非遞迴遍歷演算法
void InOrderTraverse_NoRecursion(BiTree t)
{
BiTree stack[maxsize];
int top=-1;
while(t||top!=-1)
{
while(t)
{
stack[++top]=t;
t=t->lchild;
}
if(top!=-1)
{
t=stack[top--];
printf("%c ",t->data);
t=t->rchild;
}
}
}
// 後序遍歷非遞迴遍歷演算法(方法很多種)
//先序是:DLR,後序是:LRD,左右孩子顛倒的先序是 :DRL
//把DRL壓棧再輸出就是LRD
void PostOrderTraverse_NoRecursion(BiTree t)
{
BiTree stack1[maxsize];
char stack2[maxsize];
int top=-1,top2=0;
while(t||top!=-1)
{
while(t)
{
stack2[top2++]=t->data;
stack1[++top]=t;
t=t->rchild;
}
if(top!=-1)
{
t=stack1[top--];
t=t->lchild;
}
}
while(top2--)
{
printf("%c ",stack2[top2]);
}
}
int main()
{
BiTree binarytree;
BiTreecreate(binarytree);
printf("二叉樹 bt:");
pre_order_traveral_brackets(binarytree);
printf("\n***層次遍歷序列:");
LevelOrderTravese1(binarytree);
printf("\n先序遍歷序列:");
printf("\n遞迴演算法:");
PreOrderTraverse(binarytree);
printf("\n非遞迴演算法:");
PreOrderTraverse_NoRecursion(binarytree);
printf("\n中序遍歷序列:");
printf("\n遞迴演算法:");
InOrderTraverse(binarytree);
printf("\n非遞迴演算法:");
InOrderTraverse_NoRecursion(binarytree);
printf("\n後序遍歷序列:");
printf("\n遞迴演算法:");
PostOrderTraverse(binarytree);
printf("\n***非遞迴演算法:");
PostOrderTraverse_NoRecursion(binarytree);
}