PTA 树种统计 c语言-------二叉搜索树 详细解释

树种统计

这题乍一瞅写个树种,但是再一看貌似跟树没啥关系啊。

随着卫星成像技术的应用,自然资源研究机构可以识别每一棵树的种类。请编写程序帮助研究人员统计每种树的数量,计算每种树占总数的百分比。

输入格式:
输入首先给出正整数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);
}

这里我用的数组的方法保存树
当然也可以用链表储存,但是链表消耗内存过大。。。个人不太建议。

发布了11 篇原创文章 · 获赞 9 · 访问量 545

猜你喜欢

转载自blog.csdn.net/VistorsYan/article/details/103178359