## 树的应用题:
数据结构分为线性结构和非线性结构两大类。树和二叉树是非线性结构中非常重要的一员,它适合描述具有层次结构的数据。
- 如果将学生的百分制成绩分为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])) ;
}
}
支持可以关注我哦,持续分享编写的代码。