求二叉树 叶节点数 深度 非递归先序遍历 层序遍历 交换左右子树 双孩子节点 单孩子节点

本文介绍了一种使用C语言实现二叉树的操作及遍历的方法,包括创建、多种遍历方式(如先序、中序、后序、层次遍历等),以及一些实用的功能如计算树的深度、叶子节点数、单孩子节点数和双孩子节点数,并提供了交换左右子树的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

废话不多说,直接上代码

#include <stdio.h>
#include <malloc.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h> 
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define INFEASIBLE -2

#define MAX_STACK 100
#define SIZE 100
#define Max_Tree_SIZE 20
typedef int Status;
typedef char TElemType;
typedef int Status;

typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild,*rchild; 
}BiTNode,*BiTree;

typedef BiTree SElemType;
typedef BiTree QElemType;


typedef struct{
        BiTree *base;
        int top; //指示栈顶位置
}SqStack;

void InitStack(SqStack *S) {
	S->base=(BiTree*)malloc(MAX_STACK*sizeof(BiTree));
	S->top=-1;
} 

void Push(SqStack *S,BiTree e){  
		if (S->top == MAX_STACK-1) 
           printf("\nStack is full"); 
         else {
		 	S->base[++S->top]=e;
		 }
           
}//12#34##5##67##8##
void Pop(SqStack *S,BiTree *e){  
		if (S->top == MAX_STACK-1) 
           printf("\nStack is empty"); 
         else 
           *e=S->base[S->top--];
}

void GetTop(SqStack S, SElemType *e) {  
         if (S.top == -1)  
           printf("\nStack is empty");
         else 
           *e=S.base[S.top];
}      
void printStack(SqStack S){
	printf("\n");
	while(S.top!=-1){
		printf("%d ",S.base[S.top--]);
	}
}

typedef struct queue{
        QElemType *base;
        int front; //指示队头位置
        int rear;  //指示队尾位置
}SqQueue;

void initQueue(SqQueue *q){
	q->base = (QElemType*)malloc(SIZE*sizeof(QElemType));
	q->front=q->rear=0;
}

void enQueue(SqQueue *q,QElemType e){
		q->base[q->rear]=e;
		q->rear++;
}

void deQueue(SqQueue *q,QElemType *e){
		*e=q->base[q->front];
		q->front++;
}

Status InitBiTree(BiTree *);
Status CreateBiTree(BiTree *);
Status PreOrder(BiTree);
Status InOrder(BiTree);
Status PostOrder(BiTree);

Status LevelOrder(BiTree);
Status NRPreOrder(BiTree);

int TreeDepth(BiTree);
int LeafNumber(BiTree);


int oneChild(BiTree BT){//求二叉树的单孩子节点的个数 
	int n=0;
	if(BT){
		if(!BT->lchild&&BT->rchild||BT->lchild&&!BT->rchild){//该节点为单孩子节点 
			n=1;
		} 
		return oneChild(BT->lchild)+oneChild(BT->rchild)+n; //递归求解左右子树 
	}
	return 0;
}

int twoChilds(BiTree BT){//求二叉树的双孩子节点的个数 
	int n=0;
	if(BT){
		if(BT->lchild&&BT->rchild){//该节点有两个孩子 
			n=1;
		} 
		return twoChilds(BT->lchild)+twoChilds(BT->rchild)+n; //递归求解左右子树 
	}
	return 0;
}
void excTree(BiTree *BT){//交换二叉树的左右子树 
	if((*BT)){
		//左右递归 
		excTree(&(*BT)->lchild);
		excTree(&(*BT)->rchild);
		//交换左右子数 
		BiTree temp=(*BT)->lchild;
		(*BT)->lchild=(*BT)->rchild;
		(*BT)->rchild=temp;
	}
}
void main(){
	BiTree BT;
	TElemType ch;
	
	int flag=1,select;
	
	printf("\n");
	printf("To Create Binary Tree,Please Input PreOrder with '#'");
	
	CreateBiTree(&BT);
		printf("Please select:\n");
		printf("1.PreOrder Traversal \n"); 
		printf("2.InOrder Traversal \n"); 
		printf("3.PostOrder Traversal \n"); 
		printf("4.LevelOrder Traversal \n"); 
		printf("5.NROrder Traversal \n"); 
		printf("6.TreeDepth  \n"); 
		printf("7.LeafNumber  \n"); 
		printf("8.oneChild   \n"); 
		printf("9.twoChilds   \n"); 
		printf("10.excTree   \n"); 
		printf("11.Exit \n"); 
	while(flag){
		
		
		scanf("%d",&select);
		switch(select){
			case 1:printf("\nThe PreOrder Traversal of Binary Tree is:");
				   PreOrder(BT);break;
			case 2:printf("\nThe InOrder Traversal of Binary Tree is:");
				   InOrder(BT);break;
			case 3:printf("\nThe PostOrder Traversal of Binary Tree is:");
				   PostOrder(BT);break;
			case 4:printf("\nThe LevelOrder Traversal of Binary Tree is:");
				   LevelOrder(BT);break;
			case 5:printf("\nThe NRPreOrder Traversal of Binary Tree is:");
				   NRPreOrder(BT);break;
			case 6:printf("\nThe The Depth of Binary Tree is:%d",TreeDepth(BT));
				   break;
			case 7:printf("\nThe Number of leaf is:%d",LeafNumber(BT));
				   break;
			case 8:printf("\nThe Number of oneChild is:%d",oneChild(BT));
				   break;
			case 9:printf("\nThe Number of twoChilds is:%d",twoChilds(BT));
				   break;
			case 10:printf("\nexcTree success!");
					excTree(&BT);
				   break;
			default:flag=0;
				   printf("Press any key to exit!\n");
				   getch();   
			
		}
		printf("\n");
	}
}

Status InitBiTree(BiTree *BT){
	*BT=NULL;
	return OK;
}
Status CreateBiTree(BiTree *BT){
	TElemType ch=getchar();
	if(ch!='#'){
		*BT = (BiTree)malloc(sizeof(BiTNode));
		(*BT)->data=ch;
		CreateBiTree(&((*BT)->lchild));
		CreateBiTree(&((*BT)->rchild));
	}else{
		*BT=NULL;
	}
	
	return OK;
}
Status PreOrder(BiTree BT){
	if(BT!=NULL){
		printf("%c",BT->data);
		PreOrder(BT->lchild);
		PreOrder(BT->rchild);
	}
	return OK;
}
Status InOrder(BiTree BT){
	if(BT!=NULL){
		
		InOrder(BT->lchild);
		printf("%c",BT->data);
		InOrder(BT->rchild);
	}
	return OK;
}
Status PostOrder(BiTree BT){
	if(BT!=NULL){
		
		PostOrder(BT->lchild);
		PostOrder(BT->rchild);
		printf("%c",BT->data);
	}
	return OK;
}

Status LevelOrder(BiTree BT){//二叉树的层序遍历 
	SqQueue q;
	BiTree T=BT; 
	initQueue(&q);
	enQueue(&q,T);
	while(q.front!=q.rear){
		deQueue(&q,&T);
		printf("%c ",T->data); 
		if(T->lchild)
			enQueue(&q,T->lchild);
		if(T->rchild)
			enQueue(&q,T->rchild);
	}
	return OK;
}
Status NRPreOrder(BiTree bt){//非递归先序遍历 

    SqStack S;
    InitStack(&S);
    if(bt==NULL)  return OK;
    BiTree p=bt;

    while(p||S.top!=-1){
    	
    	while(p){
    		printf("%c ",p->data);
    		Push(&S,p);
    		p=p->lchild;
		}
		
		if(S.top!=-1){
			Pop(&S,&p);
			p=p->rchild;
		}

	}
	return OK;
}

int TreeDepth(BiTree BT){//求二叉树的深度 
	if(BT){
		int a=TreeDepth(BT->lchild);
		int b=TreeDepth(BT->rchild);
		return (a > b ? a : b)+1;
	}
	return 0;
}
int LeafNumber(BiTree BT){//求二叉树的叶节点数 
	if(BT){
		if(!BT->lchild&&!BT->rchild)//叶节点返回1 
			return 1;
		return LeafNumber(BT->lchild)+LeafNumber(BT->rchild);//递归求解左右子树 
	}
	return 0;
}
/*
测试数据:
12#34##5##67##8##
*/ 

 

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值