#include<stdio.h>
#include<stdlib.h>
#define DataType char
#define MAXSIZE 50
#define MaxSize 50
int count=0;//统计叶子结点个数
int count1=0;//统计结点个数
typedef struct Node{
DataType data;
struct Node *Lchild;
struct Node *Rchild;
}BiTNode,*BiTree;
//队列
typedef struct{
BiTree data[MAXSIZE];
int rear,front;//队头队尾指针
}SeQueue;
int EmptyQueue(SeQueue *sq){
int m;
if(m=(sq->rear-sq->front)==0) return 1;
else return 0;
}
SeQueue *InitQueue(){
SeQueue *sq;
sq=(SeQueue*)malloc(sizeof(SeQueue));
sq->front=sq->rear=0;
return sq;
}
int InQueue(SeQueue *sq,DataType x){
int m;
if(m=(sq->rear)-sq->front==MAXSIZE)
return 0;
else{
sq->data[sq->rear]=x;
sq->rear++
return 1;
}
}
int OutQueue(SeQueue *sq,DataType *x){
int m;
if(m=(sq->rear)-(sq->front)==0)
return 0;
else{
*x=sq->data[sq->front];
sq->front++;return 1;
}
}
DataType FrontQueue(SeQueue *sq,DataType *x){
if(EmptyQueue(sq)) return 0;
else return sq->data[sq->front];
}
typedef struct{
BiTree data[MAXSIZE];
int top;
}SeqStack;
SeqStack *Init_SeqStack(){
SeqStack *s;
s=(SeqStack*)malloc(sizeof(SeqStack));
s->top=-1;
return s;
}
int Empty_SeqStack(SeqStack *s){
if(s->top==-1) return 1;
else return 0;
}
int Push_SeqStack(SeqStack *s,BiTree x){
if(s->top==MAXSIZE-1) return 0;
else{
s->top++;
s->data[s->top]=x;
return 1;
}
}
int Pop_SeqStack(SeqStack *s,BiTree *x){
if(Empty_SeqStack(s)) return 0;
else {
*x=s->data[s->top];
s->top--;return 1;
}
}
BiTree Top_SeqStack(SeqStack *s){
if(Empty_SeqStack(s)) return 0;
else return (s->data[s->top]);
}
void CreateBiTree(BiTree *root) {
char ch;
ch=getchar();
if(ch=='^') *root=NULL;
else{
*root=(BiTree)malloc(sizeof(BiTNode));
(*root)->data=ch;
CreateBiTree(&((*root)->Lchild));
CreateBiTree(&((*root)->Rchild));
}
}
void PrintTree(BiTree root,int h){
if(root==NULL) return;
PrintTree(root->Rchild,h+1);
for(int i=0;i<h;i++) printf(" ");
printf("%c\n",root->data);
PrintTree(root->Lchild,h+1);
}
void PreOrder(BiTree root){
if(root){
printf("%c",root->data);
PreOrder(root->Lchild);
PreOrder(root->Rchild);
}
}
void InOrder(BiTree root){
if(root){
InOrder(root->Lchild);
printf("%c",root->data);
InOrder(root->Rchild);
}
}
void PostOrder(BiTree root){
if(root){
PostOrder(root->Lchild);
PostOrder(root->Rchild);
printf("%c",root->data);
}
}
//先序非递归遍历二叉树
void PreOrder2(BiTree root) {
SeqStack *S;
BiTree p;
S=Init_SeqStack();p=root;
while(p!=NULL||!Empty_SeqStack(S)){//当前结点指针及栈均空,则结束
while(p!=NULL){
printf("%c",p->data);Push_SeqStack(S,p);p=p->Lchild;//访问根结点,根指针进栈,进入左子树
}
if(!Empty_SeqStack(S)){
Pop_SeqStack(S,&p);p=p->Rchild;//根指针退栈,进入其右子树
}
}
}
//中序非递归遍历二叉树
void InOrder2(BiTree root) {
SeqStack *S;
BiTree p;
S=Init_SeqStack();p=root;
while(p!=NULL||!Empty_SeqStack(S)){
while(p!=NULL){
Push_SeqStack(S,p);p=p->Lchild;
}
if(!Empty_SeqStack(S)){
Pop_SeqStack(S,&p); printf("%c",p->data);p=p->Rchild;
}
}
}
//后序非递归遍历二叉树
void PostOrder2(BiTree root) {
SeqStack *S;
BiTree p,q;
S=Init_SeqStack();p=root;q=NULL;
while(p!=NULL||!Empty_SeqStack(S)){
while (p!=NULL){
Push_SeqStack(S,p);p=p->Lchild;
}
if(!Empty_SeqStack(S)){
p=Top_SeqStack(S);
if((p->Rchild==NULL)||(p->Rchild==q)){//判断栈顶结点的右子树是否为空,右子树是否刚访问过
Pop_SeqStack(S,&p);printf("%c",p->data);q=p;p=NULL;
}
else p=p->Rchild;
}
}
}
//求二叉树的高度
int PostTreeDepth(BiTree root) {
int hl=0,hr=0,h=0;
if(root==NULL) return 0;
else{
hl=PostTreeDepth(root->Lchild);//递归求左子树的高度
hr=PostTreeDepth(root->Rchild);//递归求右子树的高度
h=(hl>hr?hl:hr)+1; //计算树的高度
return h;
}
}
//统计二叉树中的叶子结点个数并打印出(先序 )
void PreOrder_count(BiTree root) {
if(root){
if(root->Lchild==NULL&&root->Rchild==NULL){
printf("%c",root->data);//count++;
}
PreOrder_count(root->Lchild);
PreOrder_count(root->Rchild);
}
}
//统计二叉树的结点个数(先序遍历统计二叉树中的结点数)
void PreOrder_count1(BiTree root) {
if(root){
count1++;
PreOrder_count1(root->Lchild);//先序遍历左子树
PreOrder_count1(root->Rchild);//先序遍历右子树
}
}
//计算某一k层的叶子结点个数
int LeafKLevel(BiTNode *b,int k)
{
BiTNode *Qu[MaxSize];//定义循环队列
int front, rear;//定义队首、队尾指针
int leaf=0;//leaf累计叶子节点个数
int last;//定义当前层中最右节点在队列中的位置
int level;//定义当前节点的层号
front=rear=0;//置队列为空队列
if(b==NULL||k<=1)
return 0;
rear=(rear+1)%MaxSize;//节点指针进队
Qu[rear]=b;
last=rear;level=1;//第一层的最右节点在队列中的位置为1
while(front!=rear)//队列不为空时循环
{
front=(front+1)%MaxSize;
b=Qu[front];//队头出队
if(level==k&&b->Lchild==NULL&&b->Rchild==NULL)
leaf++;//若*b为level层叶子节点,则递增1
if(b->Lchild!=NULL)//左孩子进队
{
rear=(rear+1)%MaxSize;
Qu[rear]=b->Lchild;
}
if(b->Rchild!=NULL)//右孩子进队
{
rear=(rear+1)%MaxSize;
Qu[rear]=b->Rchild;
}
if(front==last)//同层最右节点处理完毕,层数增1
{
level++;
last=rear;//让last指向下一层的最右节点在队列中的位置
}
if(level>k)//当层号大于k时返回leaf,不再继续
return leaf;
}
}
//递归遍历交换左右子树
BiTree exchange_rootFirlst(BiTree T)
{
if(T!=NULL){
if(T->Lchild!=NULL||T->Rchild!=NULL)
{
BiTree p,q;
p = exchange_rootFirlst(T->Lchild);
q = exchange_rootFirlst(T->Rchild);
T->Lchild = q;
T->Rchild = p;
}
}
return T;
}
//按先序遍历树输出节点及节点的层数
void PreOrderandLever(BiTree root,int h){
if(root!=NULL){
printf("(%c,%d)",root->data,h);
PreOrderandLever(root->Lchild,h+1);
PreOrderandLever(root->Rchild,h+1);
}
}
//按层遍历二叉树
void visitbyfloor(BiTree root){
SeQueue *Q;BiTree q,l,r;
Q=InitQueue();
if(root) InQueue(Q,root);
while(!EmptyQueue(Q)){
OutQueue(Q,&q);
printf("%c",q->data);
if(q->Lchild) InQueue(Q,q->Lchild);
if(q->Rchild) InQueue(Q,q->Rchild);
}
}
根据先序序列和中序遍历序列,建立二叉树。输出这棵二叉树的后序遍历序列。
BiTNode* CreatByPI(char *pre,char *in,int n) {
BiTNode *s;int pos;char*p;
if(n<=0) return NULL;
s=(BiTNode*)malloc(sizeof(BiTNode)) ;
s->data=*pre;
for(p=in;p<in+n;p++){
if(*p==*pre)
break;
}
pos=p-in;
s->Lchild=CreatByPI(pre+1,in,pos);
s->Rchild=CreatByPI(pre+pos+1,p+1,n-pos-1);
return s;
}
//根据中序序列和后序序列,建立二叉树。输出这棵二叉树的先序遍历序列。
BiTNode* CreatByIP(char *in,char *post,int n) {
BiTNode *s;int pos;char*p;
if(n<=0) return NULL;
s=(BiTNode*)malloc(sizeof(BiTNode)) ;
s->data=*(post+n-1);
for(p=in;p<in+n;p++){
if(*p==*(post+n-1))
break;
}
pos=p-in;
s->Lchild=CreatByIP(in,post,pos);
s->Rchild=CreatByIP(p+1,post+pos,n-pos-1);
return s;
}
//求出字符串长度
int Lengthofstring(char*s){
char *p=s;int count=0;
while(*p!='\0'){
count++;
p++;
}
return count;
}
int main(){
BiTree k;int h=0;
CreateBiTree(&k);
PrintTree(k,h);
printf("\n输出结果为:\n");
printf("递归先序:");
PreOrder(k);
printf("\n递归中序:");
InOrder(k);
printf("\n递归后序:");
PostOrder(k);
printf("\n非递归先序:");
PreOrder2(k);
printf("\n非递归中序:");
InOrder2(k);
printf("\n非递归后序:");
PostOrder2(k);
printf("\n叶子结点为:") ;
PreOrder_count(k);
PreOrder_count1(k) ;
printf("\n总结点个数为:%d",count1);
printf("\n叶子结点个数为:%d",count);
printf("\n二叉树的高度为:%d",PostTreeDepth(k));
printf("\n%d",LeafKLevel(k,5));
}
二叉树的应用
最新推荐文章于 2023-02-02 14:14:31 发布