【实现一个二叉树管理功能,结点存储字符串】

//简单二叉树
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define max  32
typedef struct tagNode{
	char NName[max];
	struct tagNode *pL,*pR;
}TNode, *PNode;
typedef struct {
	PNode *elem;
	int front,rear;
	int queuesize;
}XhQueue;
void InitQueue(XhQueue &Q,int maxsize)
{
	Q.elem=new PNode[maxsize];
	if(Q.elem!=NULL){
		Q.front=Q.rear=0;
		Q.queuesize=maxsize;
	}
}
void EnQueue(XhQueue &Q,PNode p){
	if((Q.rear+1)%Q.queuesize!=Q.front){
		Q.elem[Q.rear]=p;
        Q.rear=(Q.rear+1)%Q.queuesize;
	}
}
void DeQueue(XhQueue &Q,PNode &p){
	if(Q.front!=Q.rear){
		p=Q.elem[Q.front];
        Q.front=(Q.front+1)%Q.queuesize;
	}
}
void GetHead(XhQueue &Q,PNode &p){
	if(Q.front!=Q.rear){
		p=Q.elem[Q.front];
	}
}
int EmQueue(XhQueue Q){
	if(Q.front!=Q.rear)return 0;
	else return 1;
}
void create(PNode &Root)
{
	char sz[max];
	scanf("%s",sz);
	if(strcmp(sz,"#")==0)
		Root = NULL;
	else{
		Root = new TNode;
		strcpy(Root->NName,sz);
		create(Root->pL);
		create(Root->pR);
	}
}
void PreOrder(PNode Root)
{
	if(Root != NULL)
	{
		printf("%s ",Root->NName);
		PreOrder(Root->pL);
		PreOrder(Root->pR);
	}
}
void Aoru(PNode Root,int indent)
{
	if(Root != NULL){
		for(int i=0;i<indent;i++)
			printf("\t");
		printf("%s\n",Root->NName);

		Aoru(Root->pL,indent+1);
		Aoru(Root->pR,indent+1);

	}
}
void Layer(PNode Root)
{
	XhQueue q;
	PNode p;
	InitQueue(q,100);
	if(Root!=NULL)
		EnQueue(q,Root);
	while(EmQueue(q)==0)
	{
		DeQueue(q,p);
		printf("%s ",p->NName);
		if(p->pL!=NULL)
		EnQueue(q,p->pL);		
		if(p->pR!=NULL)
			EnQueue(q,p->pR);		
	}
}
void Find(PNode Root, char *name, PNode &f)
{
	if(Root)
	{
		printf("%s", Root->NName);
		if(strcmp(Root->NName,name)==0){
			f = Root;
		}
		Find(Root->pL, name, f);
		Find(Root->pR, name, f);
	}
}
void Destroy(PNode p)
{
	if(p)
	{
		Destroy(p->pL);
		Destroy(p->pR);
		delete p;
	}
}
void Delete(PNode& Root, char *name){

	if(Root)
	{
		if(strcmp(Root->NName,name)==0){
			Destroy(Root);
			Root = NULL;
		}
		else{
			Delete(Root->pL, name);
			Delete(Root->pR, name);
		}
	}
}
void Find2(PNode Root, char *name, PNode &f)
{
	if(Root)
	{
		if(strcmp(Root->NName,name)==0){
			f = Root;
		}
		Find2(Root->pL, name, f);
		Find2(Root->pR, name, f);
	}
}
void Insert(PNode Root, char *pname, char *cname)
{
	PNode parent,pnew;
	Find2(Root,pname, parent);
	if(parent==NULL){
		printf("父结点不存在\n");
		return;
	}else{
		if(parent->pL&&parent->pR){
			printf("子结点已满\n");
			return;
		}
		if(parent->pL){
			if(strcmp(parent->pL->NName,cname)==0){
				printf("同名子结点已存在\n");
				return;
			}
		}
		if(parent->pR){
			if(strcmp(parent->pR->NName, cname)==0){
				printf("同名子结点已存在\n");
				return;
			}
		}			
		pnew = new TNode;pnew->pL=pnew->pR=NULL;
		strcpy(pnew->NName, cname);		
		if(parent->pL==NULL)
			parent->pL = pnew;
		else
			parent->pR=pnew;
	}
}
int decide(PNode T)
{
	if(T==0)
	return 0;
    TNode a[100];
	int rear=0,front=-1;
    a[rear]=*T;
    if(T->pL==NULL&&T->pR==NULL)return 1;
    if(T->pL==NULL||T->pR==NULL)return 0;
    while(front!=rear){
        front++;
        if(a[front].pL!=NULL&&a[front].pR!=NULL)
		{
            rear++;
            a[rear] = *a[front].pL;
            rear++;
            a[rear] = *a[front].pR;
        }
		else if(a[front].pL==NULL&&a[front].pR!=NULL)
            return 0;
		else if((a[front].pL!=NULL&&a[front].pR==NULL)||(a[front].pL==NULL&&a[front].pR==NULL))
		{ 
            for(int i=front+1;i<=rear;i++)
			{
                if(a[i].pL!=NULL||a[i].pR!=NULL)
                    return 0;
            }
        }
    }
    return 1;
}
menu()
{
	printf("===========主菜单============\n");
		printf("1 ---采用根 左子树 右子树的输入形式建立二叉树\n");
		printf("2 ---实现二叉树先序遍历输出\n");
		printf("3 ---实现二叉树的凹入输出\n");
		printf("4 ---实现层次遍历输出\n");	
		printf("5 ---实现查找指定名称的结点并返回指针\n");	
		printf("6 ---插入指定名称的结点\n");
		printf("7---删除指定名称的结点\n");
		printf("8---判断一棵二叉树是否为完全二叉树\n");
		printf("0----退出\n");
	    printf("请选择");
}
 main()
{
	PNode T,p;
	int choice=1;
	char sz1[32],sz2[32];
		while(choice!=0)
	{
		menu();
		scanf("%d",&choice);
		switch(choice){
		case 1:
			printf("请输入类似与字符串[ ee # # cs # #]:\n");
			create(T);
			break;
		case 2:
			PreOrder(T);
			break;
		case 3:
			Aoru(T,0);
			break;
		case 4:
			Layer(T);
			break;
		case 5:
			printf("请输入要查找结点名:");
			scanf("%s", sz1);
			Find(T, sz1, p);
			if(p)
				printf("\nnode addr = %x node val = %s\n",p,p->NName);
			else
				printf("没找到该结点\n");
			break;
		case 6:
			printf("请输入父结点名、新结点名字(中间用空格隔开):");
			scanf("%s %s", sz1,sz2);
			Insert(T, sz1, sz2);
			break;
		case 7:
			printf("请输入结点名:");
			scanf("%s", sz1);
			Delete(T, sz1);
			break;
		case 8:
			if(decide(T)==1) printf("---是\n");
			else printf("---不是\n");
			break;
		case 0:
			printf("---再见---\n");
			exit(0);
			break;
		default:
			printf("你选择错误了\n");
			break;
		}
		getchar();
		getchar();	
		system("cls");
	}
}

希望大佬能指正其中不足!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值