POJ 2418 Hardwood Species

题目大意:

        阔叶林是一种植物群落,其中的树木都具有叶子面子很大这一共同特征,多结坚果,冬天会进入休眠状态。美国的温度和气候创造了近百种阔叶物种,如橡树、枫树、樱桃树等等,阔叶树几乎占全美树种的40%左右。另一方面,针叶树(拉丁语称为”锥轴树“,因为其叶子是锥形针状的)在美国也随处可见,如雪松、冷杉、铁杉、红杉等。一般针叶树在家里被用作装饰性的木材。

       现自然资源部门使用卫星成像技术,在每一天都编制了一张图像清单,记录了一定范围内的每一颗树,先需要你编程计算每一天记录的树种的”人口结构“。

       有多个测例(测例无上限),每个测例中都会给出一张树的清单(由卫星拍摄,以树种名称给出),每一颗树占一行,树名不超过30个字符,其中树会重复出现,不会超过10,000个树种,也不会超过1,000,000棵树,对于每个测例都需要按字典升序给出每种树的树名和其占总数的百分比(截断至4位小数),每种树各占一行。

题目链接

BST:

注释代码:

/*             
 * Problem ID : POJ 2418 Hardwood Species
 * Author     : Lirx.t.Una             
 * Language   : C++     
 * Run Time   : 1110 ms             
 * Run Memory : 312 KB             
*/ 

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

//maximum length of species' name,
//物种名称的最大长度
//最后一位留给空字符
//30 + 1
#define	MAXNAMELEN		31

struct	Node;

typedef	struct	Node *		PtNode;
typedef	struct  Node *		Tree;

struct	Node {//二叉搜索树的结点
	
	char	name[MAXNAMELEN];
	
	Tree	lft;
	Tree	rht;
	
	int		cnt;//count,记录该物种出现过多少次
};

int	n;//树的总数

void
insert( Tree &tree, char *name ) {//向BST中插入一个结点
	//传的是Node指针的引用,这样可以对上层递归函数传进来的
	//father_node->lft/rht进行修改了
	
	if ( !tree ) {//若数为空就代表已经递归到了底部(叶子结点的下面一层)
		//此时可以插入该结点了

		tree = (PtNode)malloc( sizeof(Node) );
		
		strcpy( tree->name, name );
		
		tree->lft = NULL;
		tree->rht = NULL;
		tree->cnt = 1;
		
		return ;
	}
	
	int		cmp;
	
	cmp = strcmp(tree->name, name);
	
	if ( !cmp ) {//若刚好就是当前结点所代表的物种
		//就将该物种的数量加1
		
		tree->cnt++;
		return ;
	}
	
	if ( cmp < 0 )//若字母顺序小于当前结点所表示的物种就
		//插入到其左子树中
		insert( tree->rht, name );
	else//否则就插入其右子树
		insert( tree->lft, name );
}

void
travel(Tree tree) {//中序遍历
	
	if (tree) {//先左后右
		
		travel( tree->lft );
		printf("%s %.4f\n", tree->name, (double)tree->cnt / (double)n * 100.0);
		travel( tree->rht );
	}
}

int
main() {
	
	char	name[MAXNAMELEN];
	Tree	tree;
	
	tree = NULL;
	n	 = 0;
	while ( gets(name) ) {
		
		insert( tree, name );
		n++;
	}
	travel(tree);
	
	return 0;
}

无注释代码:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define	MAXNAMELEN		31

struct	Node;

typedef	struct	Node *		PtNode;
typedef	struct  Node *		Tree;

struct	Node {
	
	char	name[MAXNAMELEN];
	
	Tree	lft;
	Tree	rht;
	
	int		cnt;
};

int	n;

void
insert( Tree &tree, char *name ) {
	
	if ( !tree ) {
		
		tree = (PtNode)malloc( sizeof(Node) );
		
		strcpy( tree->name, name );
		
		tree->lft = NULL;
		tree->rht = NULL;
		tree->cnt = 1;
		
		return ;
	}
	
	int		cmp;
	
	cmp = strcmp(tree->name, name);
	
	if ( !cmp ) {
		
		tree->cnt++;
		return ;
	}
	
	if ( cmp < 0 )
		insert( tree->rht, name );
	else
		insert( tree->lft, name );
}

void
travel(Tree tree) {
	
	if (tree) {
		
		travel( tree->lft );
		printf("%s %.4f\n", tree->name, (double)tree->cnt / (double)n * 100.0);
		travel( tree->rht );
	}
}

int
main() {
	
	char	name[MAXNAMELEN];
	Tree	tree;
	
	tree = NULL;
	n	 = 0;
	while ( gets(name) ) {
		
		insert( tree, name );
		n++;
	}
	travel(tree);
	
	return 0;
}

AVL:

注释代码:

/*              
 * Problem ID : POJ 2418 Hardwood Species 
 * Author     : Lirx.t.Una              
 * Language   : GCC      
 * Run Time   : 1329 ms              
 * Run Memory : 512 KB              
*/   

#pragma GCC optimize("O2")

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define	MAXNAMELEN		31

struct	Node;

typedef	struct Node *	PtNode;
typedef	struct Node *	Tree;

struct	Node {

	char	name[MAXNAMELEN];

	Tree	lft;	
	Tree	rht;

	int		h;//每个AVL树结点还需维护
	        //该结点所代表的数的高度
	        //一边对后面左右子树高度的调整
	        //以及旋转带来依据
	int		cnt;
};

int		n;

int
Height(Tree tree) {//空结点高度为-1,
	           //单节点高度为0

	if ( !tree )
		return -1;

	return tree->h;
}

int
MaxHRL(Tree tree) {//maximum height in left tree and right tree,
	//计算左右子树两者较高的高度

	int		hl, hr;//height of left tree and right tree

	hl = Height( tree->lft );
	hr = Height( tree->rht );

	return hl > hr ? hl : hr;
}

Tree
RotL(Tree k2) {//Rotation in left,左旋转

	Tree	k1;

	k1		= k2->lft;
	k2->lft	= k1->rht;
	k1->rht	= k2;

	//旋转后,由于k2的左子树改变
	//并且k2成为了k1的子树
	//因此需要先更新k2的高度
	//然后再更新k1的高度
	k2->h	= MaxHRL(k2) + 1;
	k1->h	= MaxHRL(k1) + 1;

	return k1;
}

Tree
RotR(Tree k2) {//Rotation in right

	Tree	k1;

	k1		= k2->rht;
	k2->rht = k1->lft;
	k1->lft	= k2;

	k2->h	= MaxHRL(k2) + 1;
	k1->h	= MaxHRL(k1) + 1;

	return k1;
}

Tree
RotLR(Tree t) {//Rotation first in left,then in right,
	//双旋转,先对t的右子树左转,再对t右转

	t->rht = RotL( t->rht );

	return RotR(t);
}

Tree
RotRL(Tree t) {//Rotation first in right, then in left

	t->lft = RotR( t->lft );

	return RotL(t);
}

Tree
Insert( Tree tree, char *name ) {//向AVL中插入结点

	if ( !tree ) {
	
		PtNode	node;

		node = (PtNode)malloc( sizeof( struct Node ) );
		
		strcpy( node->name, name );
		
		node->lft = NULL;
		node->rht = NULL;
		
		node->h	  = 0;//单结点树高度为0
		node->cnt = 1;
		
		return node;
	}
	
	int		cmp;
	
	cmp = strcmp( name, tree->name );
	
	if ( !cmp ) {
		
		tree->cnt++;
		return tree;
	}
	
	if ( cmp < 0 ) {//插入物种字母顺序小于当前结点则插入到左子树中
		
		tree->lft = Insert( tree->lft, name );
		//由于插入后左子树是AVL平衡的,但是不能保证tree也是平衡的(因为这是递归插入)
		if ( 2 == Height( tree->lft ) - Height( tree->rht ) )//若不平衡
			if ( strcmp( name, tree->lft->name ) < 0 )//插入物种字母小于左子树,
				                             //这就意味着tree左偏
				return RotL(tree);
			else//否则就是大于右子树
				//不可能出现等于,因为等于就意味着没有插入结点,由于原来是AVL平衡的
				//既然没有插入结点就意味着现在也是平衡的,因此不可能会出现不平衡的情况
				return RotRL(tree);
	}
	else {//插入到右子树的情景是相同的
		
		tree->rht = Insert( tree->rht, name );
		if ( 2 == Height( tree->rht ) - Height( tree->lft ) )
			if ( strcmp( name, tree->rht->name ) > 0 )
				return RotR(tree);
			else
				return RotLR(tree);
	}
	
	//由于进行旋转时旋转函数已经将tree的高度更新了
	//但是如果插入左右子树后没出现失衡,那也就是说没有进入旋转函数过
	//因此tree的高度也就没有更新过
	//因此这里需要对tree的高度进行更新
	tree->h	= MaxHRL(tree) + 1;
	
	return tree;
}

void
Travel(Tree tree) {
	
	if (tree) {
		
		Travel( tree->lft );
		printf("%s %.4f\n", tree->name, (double)tree->cnt / (double)n * 100.0);
		Travel( tree->rht );
	}
}

int
main() {
	
	char 	name[MAXNAMELEN];
	Tree	tree;
	
	tree = NULL;
	n    = 0;
	while ( gets(name) ) {
		
		tree = Insert( tree, name );
		n++;
	}
	Travel(tree);
	
	return 0;
}

无注释代码:

#pragma GCC optimize("O2")

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define	MAXNAMELEN		31

struct	Node;

typedef	struct Node *	PtNode;
typedef	struct Node *	Tree;

struct	Node {

	char	name[MAXNAMELEN];

	Tree	lft;	
	Tree	rht;

	int		h;
	int		cnt;
};

int		n;

int
Height(Tree tree) {

	if ( !tree )
		return -1;

	return tree->h;
}

int
MaxHRL(Tree tree) {

	int		hl, hr;

	hl = Height( tree->lft );
	hr = Height( tree->rht );

	return hl > hr ? hl : hr;
}

Tree
RotL(Tree k2) {

	Tree	k1;

	k1		= k2->lft;
	k2->lft	= k1->rht;
	k1->rht	= k2;

	k2->h	= MaxHRL(k2) + 1;
	k1->h	= MaxHRL(k1) + 1;

	return k1;
}

Tree
RotR(Tree k2) {

	Tree	k1;

	k1		= k2->rht;
	k2->rht = k1->lft;
	k1->lft	= k2;

	k2->h	= MaxHRL(k2) + 1;
	k1->h	= MaxHRL(k1) + 1;

	return k1;
}

Tree
RotLR(Tree t) {

	t->rht = RotL( t->rht );

	return RotR(t);
}

Tree
RotRL(Tree t) {
	
	t->lft = RotR( t->lft );
	
	return RotL(t);
}

Tree
Insert( Tree tree, char *name ) {
	
	if ( !tree ) {
		
		PtNode	node;
		
		node = (PtNode)malloc( sizeof( struct Node ) );
		
		strcpy( node->name, name );
		
		node->lft = NULL;
		node->rht = NULL;
		
		node->h	  = 0;
		node->cnt = 1;
		
		return node;
	}
	
	int		cmp;
	
	cmp = strcmp( name, tree->name );
	
	if ( !cmp ) {
		
		tree->cnt++;
		return tree;
	}
	
	if ( cmp < 0 ) {
		
		tree->lft = Insert( tree->lft, name );
		if ( 2 == Height( tree->lft ) - Height( tree->rht ) )
			if ( strcmp( name, tree->lft->name ) < 0 )
				return RotL(tree);
			else
				return RotRL(tree);
	}
	else {
		
		tree->rht = Insert( tree->rht, name );
		if ( 2 == Height( tree->rht ) - Height( tree->lft ) )
			if ( strcmp( name, tree->rht->name ) > 0 )
				return RotR(tree);
			else
				return RotLR(tree);
	}
	
	tree->h	= MaxHRL(tree) + 1;
	
	return tree;
}

void
Travel(Tree tree) {
	
	if (tree) {
		
		Travel( tree->lft );
		printf("%s %.4f\n", tree->name, (double)tree->cnt / (double)n * 100.0);
		Travel( tree->rht );
	}
}

int
main() {
	
	char 	name[MAXNAMELEN];
	Tree	tree;
	
	tree = NULL;
	n    = 0;
	while ( gets(name) ) {
		
		tree = Insert( tree, name );
		n++;
	}
	Travel(tree);
	
	return 0;
}

单词解释:

hardwood:n, 阔叶树,硬木

hardwoods:n, 阔叶林

species:n, 物种,种类

botanical:n, 植物学的

broad:adj, 宽阔的

nut:n, 坚果

dormant:adj, 休眠的

generally:adv, 通常,一般

climate:n, 气候

biological:adj, 生物学的

characteristic:n, 特征

oak:n, 橡树

maple:n, 枫树

cherry:n, 樱桃树

softwood:n, 针叶树,软木

softwoods:n, 针叶林

conifer:n, 针叶树

cone:n, 圆锥体

bearing:n, 轴承

cone bearing:n, 圆锥轴承

needle:n, 针

widely available:广泛可见的,广泛可接触的

cedar:n, 雪松

fir:n, 冷杉

hemlock:n, 铁杉

pine:n, 松树

redwood:n, 红杉

spruce:n, 云杉

cypress:n, 柏树

primarily:adv, 主要地,首先

lumber:n, 木材

structural:adj, 建筑的,结构的

decorative:adj, 装潢用的,装饰性的

application:n, 用途,应用,应用程序

satellite:n, 人造卫星

imaging:n, 成像

satellite imaging technology:n, 卫星成像技术

resource:n, 资源(指自然资源),也可指人力资源

inventory:n, 详细目录,存货清单

compile:vt, 编制,编译

fraction:n, 部分,小部分

alphabetical:adj, 按字母顺序的

percentage:n, 百分比

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值