树种统计
这题乍一瞅写个树种,但是再一看貌似跟树没啥关系啊。
随着卫星成像技术的应用,自然资源研究机构可以识别每一棵树的种类。请编写程序帮助研究人员统计每种树的数量,计算每种树占总数的百分比。
输入格式:
输入首先给出正整数N(≤10
5
),随后N行,每行给出卫星观测到的一棵树的种类名称。种类名称由不超过30个英文字母和空格组成(大小写不区分)。
输出格式:
按字典序递增输出各种树的种类名称及其所占总数的百分比,其间以空格分隔,保留小数点后4位。
第一眼直观感受是用数组常规排序??? 但是看了一眼给的案例,这么老些,而且N是小于等于10的五次方。。用数组常规排序肯定超时。
这么大的数据量要想排序并输出只能想到的是二分法。因为二分法时间复杂度O(logN)。根据二维图像,可以想象数据量越大,O(logN)会越来越趋近与O(1)
在回归这道题,数组里的二分法是去查找元素。。 而这道题是把元素按顺序输出,所以还是不行。。。。
最后想了想二分法在树里的应用
二叉搜索树
在输入时就开始构造二叉搜索树。。
然后中序遍历输出就可以了。。。
左中右 正好是有小到大。。
至于后面那个频率,加个计数器,最后除以总数就可以了。
/**
思路:已二叉搜索树的方式保存输入的名称,并赋予一个计数器。然后中序遍历输出
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Null -1
struct TreeNode{
char data[31];
int left,right;
int k;//计数器
}tree[100000];
void InVisit(struct TreeNode Tree,int n){
if (Tree.left == Null && Tree.right == Null) {
printf("%s %.4f%%\n",Tree.data,Tree.k/(double)n*100);
return;
}
if (Tree.left!=Null) {
InVisit(tree[Tree.left],n);
}
printf("%s %.4f%%\n",Tree.data,Tree.k/(double)n*100);
if (Tree.right!=Null) {
InVisit(tree[Tree.right],n);
}
}
int main() {
int n,i,temp = 0,flag = 1;
scanf("%d",&n);
for (i = 0; i<n; i++) {
tree[i].k = 0;
tree[i].left = Null;
tree[i].right = Null;
}
getchar();
for (i = 0; i<n; i++) {
gets(tree[i].data);
//二叉搜索树插入 数组保存法
while (flag) {
if (strcmp(tree[i].data, tree[temp].data)<0) {
if (tree[temp].left!=Null) {
temp = tree[temp].left;
}else{
tree[temp].left = i;
tree[i].k++;
flag = 0;
}
}else if (strcmp(tree[i].data, tree[temp].data)>0){
if (tree[temp].right!=Null) {
temp = tree[temp].right;
}else{
tree[temp].right = i;
tree[i].k++;
flag = 0;
}
}else{
tree[temp].k++;
flag = 0;
}
}
flag = 1;
temp = 0;
}
//中序遍历
InVisit(tree[0],n);
}
这里我用的数组的方法保存树
当然也可以用链表储存,但是链表消耗内存过大。。。个人不太建议。