数据结构实验报告3

一.最大代价路径

1.问题分析

采用递归算法,当一个节点的子树存在时,返回其左右子树与该节点和的最大值。

2.解题思路

二叉树存储结构

typedef struct BiTNode {
	int data;			  //结点元素 
	struct BiTNode* lchild;	  //左孩子指针 
	struct BiTNode* rchild;	  //右孩子指针 
}BiTNode, *BiTree;	

创建二叉树

BiTree Create(){//输入-1代表该节点为空
	int data;
	int temp;
	BiTree T;
	scanf("%d",&data);
	temp=getchar();
	if(data==-1) {
		return NULL;
	}
	else{
		T=(BiTree)malloc(sizeof(BiTNode));
		T->data=data;
		printf("输入%d的左子树:",data);
		T->lchild=Create();
		printf("输入%d的右子树:",data);
		T->rchild=Create();
		return T; 
	}
}

递归求最大代价路径

int Max(int a,int b){
	return (a>b?a:b);
} 
int RouteSumMax(BiTree T){
	if(T==NULL) return 0;
	else return Max(T->data+RouteSumMax(T->lchild),T->data+RouteSumMax(T->rchild));
}
void Route(BiTree T){
	if(T){
		printf("%d ",T->data);
		if(RouteSumMax(T->lchild)>=RouteSumMax(T->rchild)){
			Route(T->lchild);
		}
		else{
			Route(T->rchild);
		}
	}
}

3.程序出现的BUG

没有出现BUG

4.实验总结:对于有关二叉树的算法,采用递归可以很有效的解决问题

5.附录-源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct BiTNode {
	int data;			  //结点元素 
	struct BiTNode* lchild;	  //左孩子指针 
	struct BiTNode* rchild;	  //右孩子指针 
}BiTNode, *BiTree;	//二叉树结点与指向二叉树结点的指针
//创建二叉树
BiTree Create(){//输入-1代表该节点为空
	int data;
	int temp;
	BiTree T;
	scanf("%d",&data);
	temp=getchar();
	if(data==-1) {
		return NULL;
	}
	else{
		T=(BiTree)malloc(sizeof(BiTNode));
		T->data=data;
		printf("输入%d的左子树:",data);
		T->lchild=Create();
		printf("输入%d的右子树:",data);
		T->rchild=Create();
		return T; 
	}
}
//最大代价路径
int Max(int a,int b){
	return (a>b?a:b);
} 
int RouteSumMax(BiTree T){
	if(T==NULL) return 0;
	else return Max(T->data+RouteSumMax(T->lchild),T->data+RouteSumMax(T->rchild));
}
void Route(BiTree T){
	if(T){
		printf("%d ",T->data);
		if(RouteSumMax(T->lchild)>=RouteSumMax(T->rchild)){
			Route(T->lchild);
		}
		else{
			Route(T->rchild);
		}
	}
}
int main(){
	BiTree T;
	T=Create();
	system("cls");
	printf("最大代价路径:");
	Route(T);
	printf("\n"); 
	int mcp=RouteSumMax(T);
	printf("最大路径代价:%d\n",mcp);
	return 0;
} 

效果展示:

输入:

 输出:

 二、二叉树中数据域值大于50的节点

1.问题分析

如何计算结点所在层数:对二叉树进行层序遍历,当一层的节点全部出队后,队列中剩余结点是下一层的结点,此时队列中的结点个数就是下一层的结点个数,根据每一层结点个数来确定某个结点所在层数

2.解题思路

二叉树存储结构

typedef struct bitnode{
	int data;
	int number;//结点序号
	struct bitnode *lchild;
	struct bitnode *rchild;
}bitnode,*bitree;

队列

typedef struct queue{
	bitree a[MAX];
	int front;
	int rear;
	int num;
}queue,*queueptr;

队列基本操作(初始化,判空,入队出队,队列长度)

void Init(queueptr q){
	q->front=q->rear=0;
	q->num=0;
}
int queueEmpty(queue q){
	if(q.front==q.rear) return 1;
	else return 0;
}
void enqueue(queueptr q,bitree e){
	if(q->rear>=MAX) return ;
	q->a[q->rear]=e;
	q->rear++;
	q->num++;
}
void dequeue(queueptr q,bitree *e){
	*e=q->a[q->front];
	q->front++;
	q->num--;
}
int getLengh(queueptr q){
	return q->num;
}

存储大于50结点的数组

typedef struct node{
	int levelnum;//层数
	int val;//值
	int serial;//序号
}node;

创建二叉树

bitree Create(){
	int data;
	int temp;
	bitree T;
	scanf("%d",&data);
	temp=getchar();
	if(data==-1) {
		return NULL;
	}
	else{
		T=(bitree)malloc(sizeof(bitnode));
		T->data=data;
		printf("输入%d的左子树:",data);
		T->lchild=Create();
		printf("输入%d的右子树:",data);
		T->rchild=Create();
		return T; 
	}
}

为二叉树每个结点编号

void Serial(bitree t){
	if(!t) return;
	bitree p;
	queue Q;
	queueptr q=&Q;
	int k=1;
	Init(q);
	enqueue(q,t);
	while(!queueEmpty(Q)){
			dequeue(q,&p);
			p->number=k;
			k++;
			if(p->lchild) enqueue(q,p->lchild);
			if(p->rchild) enqueue(q,p->rchild);
		}
	
}

求data域大于50的结点

void GetMorethan50(bitree t){
	int total[100];
	node morethan[100]; 
	for(int j=0;j<100;j++){
		total[j]=0;
	}
	bitree p;
	queue Q;
	queueptr q=&Q;
	Init(q);
	enqueue(q,t);
	int level=1;
	int num=1;
	int i,j;
	for(j=0;j<100;j++){
		morethan[j].levelnum=0;
		morethan[j].serial=0;
		morethan[j].val=0;
	}
	j=0;
	while(!queueEmpty(Q)){
		for(i=1;i<=num;i++){
			dequeue(q,&p);
			if(p->data>50) {
				total[level]++;
				morethan[j].levelnum=level;
				morethan[j].serial=p->number;
				morethan[j].val=p->data;
				j++;
			}
			if(p->lchild) enqueue(q,p->lchild);
			if(p->rchild) enqueue(q,p->rchild);
		}
		num=getLengh(q);
		level++;
	}
	for(i=1;i<level;i++){
		printf("第%d层大于50的数有%d个\n",i,total[i]);
		for(j=0;j<MAX;j++){
			if(morethan[j].levelnum==i){
				printf("序号:%d 数值:%d\n",morethan[j].serial,morethan[j].val);
			}
		} 
	}
}

3.出现的BUG及解决方法

BUG:输出的序号不正确,如多输出一些序号且该序号为奇怪的数字

解决方法:原因是因为morethan数组未初始化,将数组初始化即可

4.实验总结:本实验本质上还是二叉树的层次遍历,通过本实验让我学会了确定某个结点在二叉树中的层数的方法

5.附录-源码

#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct bitnode{
	int data;
	int number;
	struct bitnode *lchild;
	struct bitnode *rchild;
}bitnode,*bitree;
typedef struct queue{
	bitree a[MAX];
	int front;
	int rear;
	int num;
}queue,*queueptr;
typedef struct node{
	int levelnum;
	int val;
	int serial;
}node;
//队列基本操作
void Init(queueptr q){
	q->front=q->rear=0;
	q->num=0;
}
int queueEmpty(queue q){
	if(q.front==q.rear) return 1;
	else return 0;
}
void enqueue(queueptr q,bitree e){
	if(q->rear>=MAX) return ;
	q->a[q->rear]=e;
	q->rear++;
	q->num++;
}
void dequeue(queueptr q,bitree *e){
	*e=q->a[q->front];
	q->front++;
	q->num--;
}
int getLengh(queueptr q){
	return q->num;
}
//创建二叉树
bitree Create(){
	int data;
	int temp;
	bitree T;
	scanf("%d",&data);
	temp=getchar();
	if(data==-1) {
		return NULL;
	}
	else{
		T=(bitree)malloc(sizeof(bitnode));
		T->data=data;
		printf("输入%d的左子树:",data);
		T->lchild=Create();
		printf("输入%d的右子树:",data);
		T->rchild=Create();
		return T; 
	}
}
void Serial(bitree t){
	if(!t) return;
	bitree p;
	queue Q;
	queueptr q=&Q;
	int k=1;
	Init(q);
	enqueue(q,t);
	while(!queueEmpty(Q)){
			dequeue(q,&p);
			p->number=k;
			k++;
			if(p->lchild) enqueue(q,p->lchild);
			if(p->rchild) enqueue(q,p->rchild);
		}
	
}
void GetMorethan50(bitree t){
	int total[100];
	node morethan[100]; 
	for(int j=0;j<100;j++){
		total[j]=0;
	}
	bitree p;
	queue Q;
	queueptr q=&Q;
	Init(q);
	enqueue(q,t);
	int level=1;
	int num=1;
	int i,j;
	for(j=0;j<100;j++){
		morethan[j].levelnum=0;
		morethan[j].serial=0;
		morethan[j].val=0;
	}
	j=0;
	while(!queueEmpty(Q)){
		for(i=1;i<=num;i++){
			dequeue(q,&p);
			if(p->data>50) {
				total[level]++;
				morethan[j].levelnum=level;
				morethan[j].serial=p->number;
				morethan[j].val=p->data;
				j++;
			}
			if(p->lchild) enqueue(q,p->lchild);
			if(p->rchild) enqueue(q,p->rchild);
		}
		num=getLengh(q);
		level++;
	}
	for(i=1;i<level;i++){
		printf("第%d层大于50的数有%d个\n",i,total[i]);
		for(j=0;j<MAX;j++){
			if(morethan[j].levelnum==i){
				printf("序号:%d 数值:%d\n",morethan[j].serial,morethan[j].val);
			}
		} 
	}
}
int main(){
	bitree t;
	t=Create();
	system("cls");
	Serial(t);
	GetMorethan50(t);
	return 0; 
} 

实验效果

输入:

输出:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Crystal_node

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

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

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

打赏作者

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

抵扣说明:

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

余额充值