数据结构 实现树的一系列操作

题目:
二叉树的建立,遍历及其应用设树结点的元素类型为ElemType(可以为char或int),实现以下二叉树的各种基本操作的程序。
实验要求:
1.通过文件读取方式,建立不少于10个结点的二叉树T;
2.用非递归方式先序遍历方式输出树T的结点
3.用非递归方式中序遍历方式输出树T的结点
4.用后序遍历方式输出树T的结点
5.用层次遍历方式输出树T的结点
6.输出树T的深度
7.输出树T的叶子节点和非叶子结点
8.主函数通过函数调用实现以上各项操作

在这里插入图片描述

#include<stdio.h> 
#define M 100


typedef struct BiTNode
{    char data;
    struct BiTNode*lchild;
    struct BiTNode*rchild;
}BiTNode,*BiTree;
BiTree create(BiTree T)
{    BiTree stack[M],p=NULL;
    int top=-1,flag;
    char ch;
    FILE*fp;
    if((fp=fopen("d.txt","r"))==NULL)
    {    printf("can not open data file\n");
        exit(0);
    }
    ch=fgetc(fp);
    while(ch!=EOF)
    {    switch(ch)  
        {    case'(':top++;stack[top]=p;flag=1;break;  
            case')':   top--;break;  
            case',':flag=2;break;  
            default:p=(BiTree)malloc(sizeof(BiTNode));  
            p->data=ch;p->lchild=p->rchild=NULL; 
            if(T==NULL)  
                T=p;  
            else  
            {   switch(flag)  
                {    case 1:stack[top]->lchild=p;break;      
                    case 2:stack[top]->rchild=p;break;  
                }  
            }
        }
        ch=fgetc(fp);
    }
    fclose(fp);
    return T;
}


void preorder(BiTree T){
	BiTree stack[M];
	int top=-1;
	BiTree p=T;
	while(p!=NULL||top!=-1){
		if(p!=NULL){
			stack[++top]=p;
			printf("%c",p->data);
			p=p->lchild;
			
		}else{
			p=stack[top--];
			p=p->rchild;
		}
	}
}


void inorder(BiTree T){
	BiTree *stack[M];
	int top=-1;
	BiTree p=T;
	while(p!=NULL||top!=-1){
		if(p!=NULL){
			stack[++top]=p;
			p=p->lchild;
		}else{
			p=stack[top--];
			printf("%c",p->data);
			p=p->rchild;
		}
	}
}
void postorder(BiTree T)
{    if(T!=NULL)
    {    postorder(T->lchild);
        postorder(T->rchild);
        printf("%c",T->data);
    }
}

void levelorder(BiTree T){
	BiTree queue[M];
	int front=0;
	int rear=0;
	BiTree p=T;
	queue[rear++]=p;
	while(p!=NULL){
		p=queue[front++];
		printf("%c",p->data);
		if(p->lchild){
			queue[rear++]=p->lchild;
		}
		if(p->rchild){
			queue[rear++]=p->rchild;
		}
	}
	
	
}



int LeafNum(BiTree T) {
	if (!T) {
		return 0;
	} else if (!T->lchild && !T->rchild) {
		return 1;
	} else {
		return LeafNum(T->lchild) + LeafNum(T->rchild);
	}
}

int NotLeafNum(BiTree T) {
	if (!T) {
		return 0;
	} else if (!T->lchild && !T->rchild) {
		return 0;
	} else {
		return NotLeafNum(T->lchild) + NotLeafNum(T->rchild) + 1;
	}
}


int BiTreeDepth(BiTree T) {
	if (!T) {
		return 0;
	}
	return BiTreeDepth(T->lchild) > BiTreeDepth(T->rchild) ?
		1 + BiTreeDepth(T->lchild) : 1 + BiTreeDepth(T->rchild);
}

void main()
{    BiTree T=NULL;
    T=create(T);
    
    int lnum=LeafNum(T);
    printf("叶子结点数是:%d",lnum);
    printf("\n");
    
    int nnum=NotLeafNum(T);
    printf("非叶子结点树:%d",nnum);
    printf("\n");
    
    int depth=BiTreeDepth(T);
    printf("树的深度是:%d",depth);
    printf("\n");
    
    printf("前序遍历的结果是:");
    preorder(T);
    printf("\n");
    
    printf("中序遍历的结果是:");
    inorder(T);
    printf("\n");
    
    printf("后序遍历的结果是:");
    postorder(T);
    printf("\n");
    
    printf("层序遍历的结果是:");
    levelorder(T);
    printf("\n");
}

分析:
1.关于树的很多题目其实用递归的方法写会简化很多,例如前中后序遍历输出,也只是printf的位置不同罢了
2.树的深度问题 记得要+1,因为一开始树的深度就是为1 然后也是利用递归的思路,遍历左子树,右子树,一层一层比较深度的大小
3.叶子结点就是没有儿子的 也是递归 没有儿子return 1,然后递归找左右子树
4.非叶子结点就是有儿子的 注意我这里用到的因为前两个都是return 0的(一个条件是为空 一个条件是没有儿子)所以递归return的时候要+1

猜你喜欢

转载自blog.csdn.net/mmmm0303/article/details/106320379
今日推荐