PTA 21级数据结构与算法实验5——树和二叉树

本文涵盖了多种关于二叉树的算法问题,包括重建二叉树、朋友圈最大规模、完全二叉树的层序遍历、叶节点列举、二叉树的遍历和结构变换。同时,也涉及到了社交网络中部落的计数和成员查询,以及树的遍历与结构操作。这些问题通过递归、优先队列和并查集等数据结构与算法解决。

7-1 还原二叉树

给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。

输入格式:

输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。

输出格式:

输出为一个整数,即该二叉树的高度。

输入样例:

9
ABDFGHIEC
FDHGIBEAC

输出样例:

5
#include<stdio.h>
#include<stdlib.h>
typedef struct tree
{
    char data;
    struct tree *left,*right;
}tree;
int treeheight(tree *root)//求树的高度
{
    if(root==NULL)
        return 0;
    else
    {
        int len1=treeheight(root->left);
        int len2=treeheight(root->right);
        return len1>len2?len1+1:len2+1;
    }
}
tree* createtree(char *pre,char *in,int n)//建立树,pre是先序输入的,in是中序输入
{
    tree *root;
    root=(tree *)malloc(sizeof(struct tree));
    if(n==0)
        return NULL;
    int i;
    root->data=pre[0];
    for(i=0;i<n;i++)
        if(in[i]==root->data)
            break;
    root->left=createtree(pre+1,in,i);
    root->right=createtree(pre+i+1,in+i+1,n-i-1);
    return root;
}
int main()
{
    int n;
    scanf("%d",&n);
    char str1[n];
    char str2[n];
    scanf("%s%s",str1,str2);
    char *pre=str1;
    char *in=str2;
    tree *root=createtree(pre,in,n);
    printf("%d",treeheight(root));
    return 0;
}

7-2 朋友圈

某学校有N个学生,形成M个俱乐部。每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈。一个学生可以同时属于若干个不同的俱乐部。根据“我的朋友的朋友也是我的朋友”这个推论可以得出,如果A和B是朋友,且B和C是朋友,则A和C也是朋友。请编写程序计算最大朋友圈中有多少人。

输入格式:

输入的第一行包含两个正整数N(≤30000)和M(≤1000),分别代表学校的学生总数和俱乐部的个数。后面的M行每行按以下格式给出1个俱乐部的信息,其中学生从1~N编号:

第i个俱乐部的人数Mi(空格)学生1(空格)学生2 … 学生Mi

输出格式:

输出给出一个整数,表示在最大朋友圈中有多少人。

输入样例:

7 4
3 1 2 3
2 1 4
3 5 6 7
1 6

输出样例:

4
#include<bits/stdc++.h>
#define N 30003
using namespace std;
int family[N];//朋友数组
int find(int x)//查找函数
{
	if(x==family[x])
		return x;
	return family[x]=find(family[x]);
}
void merg(int x,int y)//并集
{
	family[find(y)] = family[x] ;
}
int main()
{  
	int i,j,n,m,kn;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
		family[i]=i;//记录所有学生的编号
	for(i=0;i<m;i++)
	{
		scanf("%d",&kn);
		int tmp1,tmp2;
		if(kn!=0);
			scanf("%d",&tmp1);
		for(j=1;j<kn;j++)
		{
			scanf("%d",&tmp2);
			if(find(tmp1) != find(tmp2)) // 这句判断不能少 否则错误
				merg(tmp1,tmp2);//查找并集
		}
	}
	int maxx=0 ;
	map<int,int>mp;
	for(i = 1;i <= n ; i++)
	{
		mp[find(i)] ++ ;
		if(mp[find(i)] > maxx)
		{
			maxx = mp[find(i)];
		}
	}
	printf("%d\n",maxx);
    return 0 ;  
}

 7-3 修理牧场

农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数Li​个长度单位,于是他购买了一条很长的、能锯成N块的木头,即该木头的长度是Li​的总和。

但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简单起见,不妨就设酬金等于所锯木头的长度。例如,要将长度为20的木头锯成长度为8、7和5的三段,第一次锯木头花费20,将木头锯成12和8;第二次锯木头花费12,将长度为12的木头锯成7和5,总花费为32。如果第一次将木头锯成15和5,则第二次锯木

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CRAEN

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

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

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

打赏作者

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

抵扣说明:

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

余额充值