数据结构-线性结构和非线性结构(二叉树)

## 树的应用题:
数据结构分为线性结构和非线性结构两大类。树和二叉树是非线性结构中非常重要的一员,它适合描述具有层次结构的数据。

  1. 如果将学生的百分制成绩分为5个等级:0-59分为不及格(E),60-69分为及格(D),70-79分为一般(C),80-89分为良好(B),90-100分为优秀(A)。在实际中,学生的成绩在五个等级上的分布是不均匀的,假设其分布概率依次为:0.05,0.14,0.29,0.36,0.16。请采用if…else判断语句设计两个不同的函数实现百分制转换为五级分制,并验证。
    要求:
    (1) 判断语句的效率最高(二叉树带权路径长度最小,用这种思想编程,不是去生成二叉树);
    (2) 判断语句的层数最小(二叉树的高度或深度最小);
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
#define MAXSIZE 100
typedef char DataType;
typedef struct Node {
	DataType data;	/*数据域*/
	struct Node *left; /*左孩子指针域*/
	struct Node *right; /*右孩子指针域*/
}BTNode, *PBTNode, *BiTreeLink;
//(1)创建二叉树 
BiTreeLink CreateBiTree(char *nodes, int pos, int num) {
	PBTNode p;
	if (nodes[pos] == ' ' || pos > num)  return NULL; /*递归结束条件*/
	p = (PBTNode)malloc(sizeof(BTNode));/*建立根结点*/
	if (!p) { printf("初始化链表错误!\n"); return 0; }
	p->data = nodes[pos];
	p->left = CreateBiTree(nodes, 2 * pos, num);	/* 递归建立左子树*/
	p->right = CreateBiTree(nodes, 2 * pos + 1, num);/* 递归建立右子树*/
	return p;
}
//显示二叉链表
void DispBiTree(BiTreeLink root) { /* root为二叉链表头指针  */
	PBTNode queue[MAXSIZE]; //循环队列
	int front, rear;		//队头队尾指针
	PBTNode p;
	if (root == NULL)	return;
	queue[0] = root;		//根结点指针入队
	front = 0;
	rear = 1;
	while (front < rear)
	{
		p = queue[front];	 //根结点指针出队
		front = (front + 1) % MAXSIZE; 
		if (p == NULL)		//	空指针显示空格
			printf("( )");
		else				//非空指针显示结点值
			printf("(%c)", p->data);
		if (p != NULL)//若双亲结点不为空,则其左孩子和右孩子指针入队
		{
			queue[rear] = p->left;
			rear = (rear + 1) % MAXSIZE;
			queue[rear] = p->right;
			rear = (rear + 1) % MAXSIZE;
		}
	}
}
void PreOrder(BiTreeLink r){
    if(r!=NULL){
        printf("%c",r->data);   /*访问根*/
        PreOrder(r->left);  /*前序遍历左子树*/
        PreOrder(r->right); /*前序遍历右子树*/
        }
} 
void InOrder(BiTreeLink r){
    if(r!=NULL){        
        InOrder(r->left);       /*中序遍历左子树*/
        printf("%c",r->data);   /*访问根*/
        InOrder(r->right);      /*中序遍历右子树*/
    }
} 
void PostOrder(BiTreeLink r){
    if(r!=NULL){    
        PostOrder(r->left);         /*后序遍历左子树*/
        PostOrder(r->right);    /*后序遍历右子树*/
        printf("%c",r->data);   /*访问根*/
    }
} 

void efficiency(int m)//每层输出不同 
{
	if(m>=80&&m<=89)
		printf("B");
	else if(m>=70&&m<=79)
		printf("C");
	else if(m>=90&&m<=100)
		printf("A");
	else if(m>=60&& m<=69)
		printf("D");
	else if(m>=0&&m<=59)
		printf("E");
}

void depth(int m,BiTreeLink root)
{
	if(m>=80)
	{
		if(m<=89)
		    
			cout<<root->data;
		else if(m<=100)
			{
			    
				cout<<root->left->data;
			}
	}
	else
	{
		if(m>=70)
			cout<<root->right->data;
		else 
		{
			if(m>=60)
				cout<<root->right->left->data;
			else
				cout<<root->right->right->data;
		}
	}
}



int main()
{
	BiTreeLink root;
	int i;
	char nodes[] = "#BAC  DE";
	root = CreateBiTree(nodes, 1, 7);
	
	int m;
	printf("请输入分数:");
	scanf("%d",&m);
	printf("效率最高时:"); 
	efficiency(m);
	printf("\n");
	printf("深度最小时:"); 
	depth(m,root);
	printf("\n");
}

2.根据下图的二叉树,计算二叉树的深度(高度)、总节点数、叶子节点数。

创建二叉树时采用顺序结构输入,某节点的左子树或右子树为空时输入字符空格或#。

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef char DataType;
typedef struct Node {
	DataType data;	//数据域
	struct Node *left; //左孩子指针域
	struct Node *right; //右孩子指针域
}BTNode, *PBTNode, *BiTreeLink;
//创建二叉树 
BiTreeLink CreateBiTree(char *nodes, int pos, int num) {
	PBTNode p;
	if (nodes[pos] == ' ' || pos > num)  return NULL; //递归结束条件
	p = (PBTNode)malloc(sizeof(BTNode));//建立根结点
	if (!p) { printf("初始化链表错误!\n"); return 0; }
	p->data = nodes[pos];
	p->left = CreateBiTree(nodes, 2 * pos, num);	// 递归建立左子树
	p->right = CreateBiTree(nodes, 2 * pos + 1, num);// 递归建立右子树
	return p;
}
//显示二叉链表
void DispBiTree(BiTreeLink root) // root为二叉链表头指针
    { 
	PBTNode queue[MAXSIZE]; //循环队列
	int front, rear;		//队头队尾指针
	PBTNode p;
	if (root == NULL)	return;
	queue[0] = root;		//根结点指针入队
	front = 0;
	rear = 1;
	while (front < rear)
	{
		p = queue[front];	 //根结点指针出队
		front = (front + 1) % MAXSIZE; 
		if (p == NULL)		//	空指针显示空格
			printf("( )");
		else				//非空指针显示结点值
			printf("(%c)", p->data);
		if (p != NULL)//若双亲结点不为空,则其左孩子和右孩子指针入队
		{
			queue[rear] = p->left;
			rear = (rear + 1) % MAXSIZE;
			queue[rear] = p->right;
			rear = (rear + 1) % MAXSIZE;
		}
	}
}
//二叉树的深度 
int BiTreeDepth(BiTreeLink r)
{
    int ld,rd;
    if(r==NULL)
	    return 0;
    else
	{
	    ld=BiTreeDepth(r->left);
		rd=BiTreeDepth(r->right);
        return ld>rd ? ld+1 : rd+1;
    }
} 
//二叉树的结点个数
int BiTreeCount(BiTreeLink r)
{
    if(r==NULL) 
	    return 0;//空二叉树的结点个数为0
    else
        return BiTreeCount(r->left)+BiTreeCount(r->right)+1;
} 
//二叉树的叶子结点个数
int LeafCount(BiTreeLink r)
{
    if(!r) 
	    return 0;/*空树叶子个数为0*/
    else if(!r->left && !r->right)/*只有根结点,叶子数为1*/
        return 1;
    else
        return LeafCount(r->left)+LeafCount(r->right);
}  
int main(int argc, char *argv[])
{
	BiTreeLink root;
	int i;
	char nodes[] = "#RAEDBFG   C  H              I  ";
	root = CreateBiTree(nodes, 1, 31);
	printf("输入序列:\n");
	for(i = 1; i <=31; i++)
	{
		printf("(%c)", nodes[i]);
	}
	printf("\n");
	printf("二叉树深度:\n");
	printf("%d\n", BiTreeDepth(root));
	printf("二叉树结点个数:\n");
	printf("%d\n", BiTreeCount(root));
	printf("二叉树叶子结点个数:\n");
	printf("%d\n", LeafCount(root));
	return 1;
}

3
已知二叉树的前序遍历序列为:ABDGCEFH,中序遍历序列为:DGBAECHF。请重建该二叉树,并按照前序序列打印输出每个节点的数据域、左孩子域和右孩子域。

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAXSIZE 100
typedef char DataType;

typedef struct Node{    
    DataType data;  /*数据域*/ 
    struct Node *left; /*左孩子指针域*/   
    struct Node *right; /*右孩子指针域*/
}BTNode,*PBTNode,*BiTreeLink;

void DispBiTree(BiTreeLink root) { /* root为二叉链表头指针  */
	PBTNode queue[MAXSIZE]; //循环队列
	int front, rear;		//队头队尾指针
	PBTNode p;
	if (root == NULL)	return;
	queue[0] = root;		//根结点指针入队
	front = 0;
	rear = 1;
	while (front < rear)
	{
		p = queue[front];	 //根结点指针出队
		front = (front + 1) % MAXSIZE; 
		if (p == NULL)		//	空指针显示空格
			printf("( )");
		else				//非空指针显示结点值
			{
			printf("(%c)", p->data);//若双亲结点不为空,则其左孩子和右孩子指针入队
			queue[rear] = p->left;
			rear = (rear + 1) % MAXSIZE;
			queue[rear] = p->right;
			rear = (rear + 1) % MAXSIZE;
		}
	}
}


struct Node *create_qianzhong(char *pre, char *mid, int n)
{
	PBTNode p;
	int i;
	if(n==0)
	return NULL;
	p=(struct Node *)malloc(sizeof(struct Node));
	p->data=pre[0];
	for(i=0;i<n;i++)
	{
		if(pre[0]==mid[i])
		break;
	}
	p->left=create_qianzhong(pre+1,mid,i);
	p->right=create_qianzhong(pre+i+1,mid+i+1,n-i-1);
	return p;
	
}

void PreOrder(BiTreeLink r){
    PBTNode stack[MAXSIZE],p;
    int top=-1;
    p=r;
    while(p||top>-1)
    {
        if(p){                      //入栈条件
            printf("%c",p->data);   //访问根结点
            stack[++top]=p;         //根结点入栈
            p=p->left;              //遍历左结点
        }else{
            p=stack[top--];
            p=p->right;             //遍历右结点
        }
    }
} 
void InOrder(BiTreeLink r){
    if(r!=NULL){        
        InOrder(r->left);       /*中序遍历左子树*/
        printf("%c",r->data);   /*访问根*/
        InOrder(r->right);      /*中序遍历右子树*/
    }                                                                           
} 

void shuchu(BiTreeLink r){
      
        BiTreeLink r1,r2;
        r1=r;
        r2=r;
        printf("根:%c ",r->data);   /*访问根*/
        r1=r->left; 
        if(r->left)
        {
		printf("左结点:%c ",r1->data); 
		}
		else
		{
			printf("左结点:# "); 
		}
        
        r2=r->right;
        if(r->right)
        {
		printf("右结点:%c \n",r2->data); 
		}
		else
		{
			printf("右结点:# \n"); 
		}
    
} 

PBTNode FindNode(BiTreeLink r,DataType x){
    PBTNode p;
    if(r==NULL) return NULL;
    if(r->data==x)   return r;
    p=FindNode(r->left,x);
    if(p) return p;
    else  return FindNode(r->right,x);
}




int main()
{
	struct Node *root;
	char qian[]="ABDGCEFH";
	char zhong[]="DGBAECHF";
	int n,i,*p;
	n=strlen(qian);
	root=create_qianzhong(qian, zhong, n);
	PreOrder(root);
	printf("\n");
	InOrder(root);
	printf("\n");
	for(i=0;i<n;i++)
	{
	shuchu(FindNode(root,qian[i])) ;
	} 

}

支持可以关注我哦,持续分享编写的代码。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火球2号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值