資料結構——二叉樹的建立和遍歷(遞迴建樹&層序遍歷建樹)
阿新 • • 發佈:2019-01-02
資料結構作業模板存檔
#include<stdio.h>
#include <cstdlib>
#include <iostream>
#include <stack>
#include<queue>
using namespace std;
//二叉樹定義
typedef char ElementType;
typedef struct BiTreeNode
{
ElementType data;
struct BiTreeNode* lchild;
struct BiTreeNode* rchild;
} BiTreeNode, *BiTree;
//遞迴的建立一棵二叉樹
//輸入為二叉樹的先序序列
void createBiTree(BiTree &T)
{
char data;
data = getchar();
if(data == '#')
{
T = NULL;
}
else
{
T = new BiTreeNode;
T->data = data;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
}
void creatBiTree_2(BiTree &rt,int n)///層序遍歷建樹
{
char root[2];
scanf("%s",root);
rt=new BiTreeNode;
rt->data=root[0];
for(int i=2; i<=n; i++)
{
BiTreeNode* T=rt;
char tmp[2];
int num=0,a[16];
scanf("%s",tmp);
int ii=i;
while(ii)
{
a[num++]=ii%2 ;
ii/=2;
}
BiTreeNode *node=new BiTreeNode;
node->data=tmp[0];
node->rchild=NULL;
node->lchild=NULL;
for(int j=num-2; j>0; j--)
if(a[j])T=T->rchild;
else T=T->lchild;
if(a[0])T->rchild=node;
else T->lchild=node;
}
}
int Nodenum(BiTreeNode* root)//二叉樹節點數目
{
if(root == NULL) return 0;
else return 1+Nodenum(root->lchild)+Nodenum(root->rchild);
}
//遞迴銷燬一棵二叉樹
void destroyBiTree(BiTree &T)
{
if(T)
{
destroyBiTree(T->lchild);
destroyBiTree(T->rchild);
delete T;
T = NULL;
}
}
//遞迴先序遍歷二叉樹
void preOrderTraverse(const BiTree &T)
{
if(T)
{
// cout<<T->data<<" ";//輸出根節點值
printf("%c ",T->data);
preOrderTraverse(T->lchild);//遍歷左子樹
preOrderTraverse(T->rchild);//遍歷右子樹
}
}
//遞迴中序遍歷二叉樹
void inOrderTraverse(const BiTree &T)
{
if(T)
{
inOrderTraverse(T->lchild);//遍歷左子樹
// cout<<T->data<<" ";//輸出根節點值
printf("%c ",T->data);
inOrderTraverse(T->rchild);//遍歷右子樹
}
}
//遞迴後序遍歷二叉樹
void postOrderTraverse(const BiTree &T)
{
if(T)
{
postOrderTraverse(T->lchild);//遍歷左子樹
postOrderTraverse(T->rchild);//遍歷右子樹
printf("%c ",T->data);
// cout<<T->data<<" ";//輸出根節點值
}
}
//遞迴求樹的深度
int depthOfBiTree(const BiTree &T)
{
int ldepth;
int rdepth;
if(T==NULL)//空樹
return 0;
ldepth = depthOfBiTree(T->lchild);
rdepth = depthOfBiTree(T->rchild);
return (ldepth>rdepth)?(ldepth+1):(rdepth+1);
}
//遞迴求二叉樹的葉子結點個數
int leafCountOfBiTree(const BiTree &T)
{
if(T==NULL)
return 0;
if(T->lchild==NULL && T->rchild==NULL)
return 1;
return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);
}
void exchangeChild(BiTree &T)///交換左右子樹
{
if(T)
{
BiTree temp = NULL;
if(T->lchild ||T->rchild)
{
temp = T->lchild;
T->lchild = T->rchild;
T->rchild = temp;
exchangeChild(T->lchild);
exchangeChild(T->rchild);
}
}
}
void LevelOrderTraverse(BiTree T)///層序遍歷
{
//Visit是對節點操作的應用函式,
//在這裡,對每個資料元素呼叫函式Visit,也即是遍歷了該節點
queue<BiTree>q;
BiTree p;
if(T)
{
q.push(T);
while(!q.empty())
{
p=q.front();
q.pop();
printf("%c ",p->data);
if(p->lchild!=NULL) q.push(p->lchild);
if(p->rchild!=NULL) q.push(p->rchild);
}
printf("\n");
}
}
int main()
{
BiTree T = NULL;
createBiTree(T);//建立二叉樹 AB#D##CE###
printf("先序遍歷: "); //先序遍歷
preOrderTraverse(T);
printf("\n");
printf("中序遍歷: ");//中序遍歷
inOrderTraverse(T);
printf("\n");
printf("後序遍歷: ");//後序遍歷
postOrderTraverse(T);
printf("\n");
printf("層序遍歷: ");
LevelOrderTraverse(T);
printf("交換左右子樹: \n");
exchangeChild(T);
printf("先序遍歷: "); //先序遍歷
preOrderTraverse(T);
printf("\n");
printf("中序遍歷: ");//中序遍歷
inOrderTraverse(T);
printf("\n");
printf("後序遍歷: ");//後序遍歷
postOrderTraverse(T);
printf("\n");
printf("層序遍歷: ");
LevelOrderTraverse(T);
printf("深度: %d\n",depthOfBiTree(T));//樹的高度
printf("葉子結點數: %d\n",leafCountOfBiTree(T));//葉子結點數
printf("總結點數量: %d\n",Nodenum(T));
destroyBiTree(T);//銷燬二叉樹,釋放空間
///================================================================
int n;
scanf("%d",&n);
BiTree TT=NULL;
creatBiTree_2(TT,n);
printf("先序遍歷: "); //先序遍歷
preOrderTraverse(TT);
printf("\n");
printf("中序遍歷: ");//中序遍歷
inOrderTraverse(TT);
printf("\n");
printf("後序遍歷: ");//後序遍歷
postOrderTraverse(TT);
printf("\n");
printf("深度: %d\n",depthOfBiTree(TT));//樹的高度
printf("葉子結點數: %d\n",leafCountOfBiTree(TT));//葉子結點數
printf("總結點數量: %d\n",Nodenum(TT));
destroyBiTree(TT);//銷燬二叉樹,釋放空間
system("PAUSE");
return EXIT_SUCCESS;
}