C语言二叉树构造遍历等备忘

//二叉树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

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

//构造二叉树
BiTree CreateBiTree(){
	BiTree T;
    char ch;
    scanf("%c",&ch);
    if(ch!='#'){
    	T=(BiTNode*)malloc(sizeof(BiTNode));
        if(!T) exit(-1);
        T->data=ch;			//先序构造 
        T->lchild=CreateBiTree();
        T->rchild=CreateBiTree();
    }
    else T=NULL;
    return T;
 }

//递归遍历traverse二叉树
int PreOrderTraverse(BiTree T){	//先序遍历 
	if(T==NULL) return 0;
	else{
		printf( " %c ",T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	} 
}

int InOrderTraverse(BiTree T){	//中序遍历 
	if(T==NULL) return 0;
	else{
		InOrderTraverse(T->lchild);
		printf(" %c ",T->data);
		InOrderTraverse(T->rchild);
	}
}

int PostOrderTraverse(BiTree T){	//后序遍历 
	if(T==NULL) return 0;
	else{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		printf(" %c ",T->data);
	}
}

//利用链栈中序遍历二叉树
int InOrderTraverse2(BiTree T){
	//构造一个存BiTree的栈
	typedef struct btreestack{
		BiTree data;
		struct btreestack *next;
	}BTstack,*Btstack;
	//初始化栈
	Btstack InitStack(){
		Btstack S;
		S=(BTstack*)malloc(sizeof(BTstack));
		S->next=NULL;
		return S;
	} 
	Btstack S=InitStack();
	//压栈
	Btstack Push(Btstack S,BiTree T){
		Btstack New=InitStack();
		New->data=T;
		New->next=S;
		S=New;
		return S;
	}
	//出栈
	BiTree pop;//保持出栈的值 
	Btstack Pop(Btstack S){
		if(!S->next) return NULL;
		pop=S->data;
		Btstack temp;
		temp=S;
		S=S->next;
		free(temp);
		temp=NULL;
		return S;
	}
	//主函数
	BiTree p=T;//游标p  
	while(p||(S->next!=NULL)){//游标p空栈也空则遍历结束 
		if(p){
			S=Push(S,p);//p不为空则把当前值压栈继续向左搜寻 
			p=p->lchild;
		}
		else{
			S=Pop(S);//p为空则把栈里暂存的上级节点出栈打印 
			printf(" %c ",pop->data);
			p=pop->rchild;/* p在栈里,p=pop->rchild把p拉到上
							级节点pop的右支继续找*/ 
		}
	}
	return 0;
} 

//用顺序栈中序遍历二叉树
int InOrderTraverse3(BiTree T){
	//定义顺序栈 MAXSIZE为40
	typedef struct{
		BiTree *base;
		BiTree *top;
		int stacksize;
	}SqStack;
	//初始化顺序栈
	SqStack InitSqstack(){
		SqStack S;
		S.base=(BiTree*)malloc(sizeof(BiTree)*40);
		if(S.base==NULL) exit(-1);
		S.top=S.base;
		S.stacksize=40;
		return S;
	} 
	SqStack S=InitSqstack();
	//入栈
	SqStack Push(SqStack S,BiTree T){
		if(S.top-S.base==S.stacksize) exit(-1);
		*S.top=T;
		S.top++;
		return S;
	} 
	//出栈
	BiTree pop;
	SqStack Pop(SqStack S){
		if(S.top==S.base) exit(-1);
		S.top--;
		pop=*S.top;
		return S;
	} 
	//判空函数 在while条件里用S.top==S.base可以 用S.top-S.base 就不行 不知道为啥
	int Empty(SqStack S){
		if(S.base==S.top)
		return 1;
		else return 0;
	} 
	//主函数
	BiTree p=T;
	while(p||!(Empty(S))){
		if(p){
			S=Push(S,p);
			p=p->lchild;
		}
		else{
			S=Pop(S);
			printf(" %c ",pop->data);
			p=pop->rchild;
		}
	}
	return 0;
} 

//用顺序队列层次遍历二叉树 
void LevelOrder(BiTree T){
	//构建顺序队列 用空一格法的循环队列 
	typedef struct{
		BiTree *base;
		int front;
		int rear;
	}SqQueue;
	//初始化队列 MAX为4
	SqQueue InitQueue(){
		SqQueue Q;
		Q.base=(BiTree*)malloc(sizeof(BiTree)*40);
		if(!Q.base) exit(-1);
		Q.rear=Q.front=0;
		return Q;
	} 
	//入队
	SqQueue enQueue(SqQueue Q,BiTree T){
		if((Q.rear+1-Q.front+4)%4==0)//队满
			{printf("full\n");return Q;}//专门改的returnQ 为了试试一个丢值的队列
		else{
			Q.base[Q.rear]=T;
			Q.rear=(Q.rear+1)%40;
		} 
		return Q;
	}
	//出队
	BiTree pop;//存出队值
	SqQueue DeQueue(SqQueue Q){
		if(Q.rear==Q.front) exit(-1);//队空
		pop=Q.base[Q.front];
		Q.front=(Q.front+1)%40;
		return Q;
	}
	int EmptyQueue(SqQueue Q){
		if(Q.rear==Q.front)
			return 1;
		else return 0;
	}
	//主程序
	SqQueue Q=InitQueue();
	Q=enQueue(Q,T);//根节点入队 
	while(!(EmptyQueue(Q))){	//队列不空则循环 
		Q=DeQueue(Q);
		printf(" %c ",pop->data);//出队上位节点  
		if(pop->lchild!=NULL){//压入子节点 
			Q=enQueue(Q,pop->lchild);
		}  
		if(pop->rchild!=NULL){
			Q=enQueue(Q,pop->rchild);
		}
	}
}

//用标志位法的顺序队列层次遍历二叉树
void LevelOrder1(BiTree T){
	//构建顺序队列 标志位为flag 表示是否开始循环 
	typedef struct{
		BiTree *base;
		int front;
		int rear;
		int flag; 
	}SqQueue;
	//初始化队列 MAX为4 标志位为flag 表示是否开始循环 
	SqQueue InitQueue(){
		SqQueue Q;
		Q.base=(BiTree*)malloc(sizeof(BiTree)*4);
		if(!Q.base) exit(-1);
		Q.rear=Q.front=0;
		Q.flag=0;
		return Q;
	} 
	int FullOrEmpty(SqQueue Q){ //队满返回1 队空返回0 否则返回2
		if(Q.front==Q.rear){
			if(Q.flag==1)
			return 1;
			else
			return 0;
		}
		return 2;
	}
	//入队
	SqQueue enQueue(SqQueue Q,BiTree T){
		int f=FullOrEmpty(Q);
		if(f==1)//队满
			exit(-1);
		else{
			Q.base[Q.rear]=T;
			if(Q.rear==3){
				Q.flag=Q.flag+1;
			}
				Q.rear=(Q.rear+1)%4;
		} 
		return Q;
	}
	//出队
	BiTree pop;//存出队值
	SqQueue DeQueue(SqQueue Q){
		int f=FullOrEmpty(Q);
		if(!f) exit(-1);//队空
		pop=Q.base[Q.front];
		if(Q.front==3){
			Q.flag=Q.flag-1;
		}
			Q.front=(Q.front+1)%4;
		return Q;
	}
	//主程序
	SqQueue Q=InitQueue();
	Q=enQueue(Q,T);//根节点入队
	int f=FullOrEmpty(Q); 
	while(f){	//队列不空则循环 
		Q=DeQueue(Q);
		printf(" %c ",pop->data);//出队上位节点 
		if(pop->lchild!=NULL){//压入子节点 
			Q=enQueue(Q,pop->lchild);
		}  
		if(pop->rchild!=NULL){
			Q=enQueue(Q,pop->rchild);
		}
	}
} 

//用链队列层次遍历二叉树
void LevelOrder2(BiTree T){
	//定义一个链队列
	typedef struct Qnode{
		BiTree data;
		struct Qnode *next;
	}QNode,*QueuePtr;
	typedef struct{
		QueuePtr front;
		QueuePtr rear;
	}QueueLink;
	//初始化
	QueueLink InitQueue(){
		QueueLink Q;
		Q.front=(QNode *)malloc(sizeof(QNode));
		if(!Q.front) exit(-1);
		Q.rear=Q.front;
		Q.front->next=NULL;
		return Q;
	} 
	QueueLink Q=InitQueue();//定义一个空队 
	//入队
	QueueLink EnQueue(QueueLink Q,BiTree T){
		QueuePtr New;/*必须用指针定义 用QNode后
									面*Q.rear->next=New会变成对空NULL赋值报错
									因为Q.rear->next=NULL*/
		New=(QueuePtr)malloc(sizeof(QNode));//别忘了要初始化分空间!!!
		if(!New) exit(-1);
		New->data=T;
		New->next=NULL;
		Q.rear->next=New;
		Q.rear=New; 
		return Q;
	} 
	//出队
	BiTree pop;//存出队值 
	QueueLink DeQueue(QueueLink Q){
		if(Q.rear==Q.front) exit(-1);
		else{
			QueuePtr p;
			p=Q.front->next;
			pop=p->data;
			Q.front->next=p->next;
			if(p==Q.rear) {
				Q.rear=Q.front;
			}
			free(p);
		}
		return Q;
	}
	//主函数
	Q=EnQueue(Q,T);
	while(!(Q.rear==Q.front)){
		Q=DeQueue(Q);
		printf(" %c ",pop->data);
		if(pop->lchild!=NULL) Q=EnQueue(Q,pop->lchild);
		if(pop->rchild!=NULL) Q=EnQueue(Q,pop->rchild);
	} 
}



//复制二叉树
BiTree Copy(BiTree T){
	if(T==NULL) return NULL;
	BiTree T_copy;
	T_copy=(BiTree)malloc(sizeof(BiTNode));
	T_copy->data=T->data;
	T_copy->lchild=Copy(T->lchild);
	T_copy->rchild=Copy(T->rchild);
	return T_copy;
} 

//求深度
int Depth(BiTree T){
	if(!T) return 0;
	int m,n;
	m=Depth(T->lchild);
	n=Depth(T->rchild);
	if(m>n) return (m+1);
	else return (n+1);
}

//求节点数
int NodeCount(BiTree T){
	if(!T) return 0;
	return (NodeCount(T->lchild)+NodeCount(T->rchild)+1);
}

//求叶子节点数
int LeafNodeCount(BiTree T){
	if(!T) return 0;
	if((T->lchild==NULL)&&(T->rchild==NULL))
	return 1;
	return (LeafNodeCount(T->lchild)+LeafNodeCount(T->rchild));
}

int main(){
	BiTree T;
	T=CreateBiTree();
	//PreOrderTraverse(T);printf("\n");
	//InOrderTraverse(T);printf("\n");
	//PostOrderTraverse(T);printf("\n");
	//InOrderTraverse2(T);printf("\n");
	//InOrderTraverse3(T);printf("\n");
	//LevelOrder(T);printf("\n");
	//LevelOrder1(T);printf("\n");
	LevelOrder2(T);printf("\n");
	BiTree T_copy=Copy(T);
	LevelOrder2(T_copy);
	int d=Depth(T);
	printf("Depth: %d\n",d);
	int nodecount=NodeCount(T);
	printf("NodeCount: %d\n",nodecount);
	int leaf=LeafNodeCount(T);
	printf("LeafNodeCount: %d \n",leaf);
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值