樹種統計
這題乍一瞅寫個樹種,但是再一看貌似跟樹沒啥關係啊。
隨着衛星成像技術的應用,自然資源研究機構可以識別每一棵樹的種類。請編寫程序幫助研究人員統計每種樹的數量,計算每種樹佔總數的百分比。
輸入格式:
輸入首先給出正整數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);
}
這裏我用的數組的方法保存樹
當然也可以用鏈表儲存,但是鏈表消耗內存過大。。。個人不太建議。