筑波院試情報システムCSの問題(27年度8月 情報1)を解いてみた。


解説します。 問題はこちら。 http://www.cs.tsukuba.ac.jp/admission/past-exam.html

二分木の問題。

(4) 深さnの完全二分木に対して、足し合わせの計算量。呼び出す回数は $ 2^{n+1}-1 $ 回。指数が $n+1$ になるのは、null checkを一番最下層のノードに対して行うから。未確認。

(5) ノードの左を子、右を兄弟とした新しいデータ構造に対して、足し合わせの関数を作成する。

int sumup_tree2(Node *p){
    if(p == NULL) return 0;
    p->data += sumup_tree2(p->left);
    return p->data + sumup_tree2(p->right);
}

確かめてみる。再帰で呼ばれるたびに木をprintしていく。木の階層ごとにprintするには多少工夫がいる。確認の全コードはこちら。C++だけどCと基本は変わらない。

#include <iostream>
#include <stdlib.h>
using namespace std;

struct Node{
    int data; Node *left; Node *right;
};
Node *root = NULL;

Node *make_node(int data, Node *left, Node *right){
    Node *p = (Node *)malloc(sizeof *p);
    p->data = data;
    p->left = left;
    p->right = right;
    return p;
}

void build_tree(){
    Node *p1,*p2,*p3,*p4,*p5;
    p5 = make_node(5,NULL,NULL);
    p4 = make_node(4,NULL,NULL);
    p3 = make_node(3,NULL,p4);
    p2 = make_node(2,p3,p5);
    p1 = make_node(1,p2,NULL);
    root = p1;
}

void print(Node *p){
    Node *rank = p;
    while (p!= NULL){
        cout << p->data << " ";
        p = p->right;
    }
    cout << endl;
    if (rank->left !=NULL)
        print(rank->left);
}

void print1(Node *p){
    cout << "Tree: "<< endl;
    print(p);
    cout << endl;
}

int sumup_tree2(Node *p){
    if(p == NULL) return 0;
    p->data += sumup_tree2(p->left);
    print1(root);
    return p->data + sumup_tree2(p->right);
}

int main(){
    build_tree();
    print1(root);
    cout << "sum: "<< sumup_tree2(root) << endl;

}
# result
Tree:   
1       
2 5     
3 4     
        
Tree:   
1       
2 5     
3 4     
        
Tree:   
1       
2 5     
3 4     
        
Tree:   
1       
9 5     
3 4     
        
Tree:   
1       
9 5     
3 4     
        
Tree:   
15      
9 5     
3 4     
        
sum: 15 

院試の過去問の解答なんてどこにも載ってないので、公開してみます。間違っていたら、Twitterから連絡くださるとうれしいです。