Skip to content

名古屋大学 情報学研究科 情報システム学専攻・知能システム学専攻 2019年8月実施 プログラミング

Author

祭音Myyura

Description

プログラム A は, ハッシュ表を用いて正整数の集合を操作するためのC言語プログラムである。 ハッシュ値ごとの正整数のリスト構造を、3つの配列 element, next, hfirst を用いて実現している。 element 配列は、正整数の集合を格納するための配列である。 next 配列は、リストの次の要素が格納されている element 配列の添え字を格納するための配列である。 hfirst 配列はハッシュ表のための配列であり、hfirst[h] はハッシュ値 h を持つ正整数のリストの先頭の要素が格納されている element 配列の添え字を表す。 ここで、hfirst[h] が -1 のときは、ハッシュ値 h を持つ正整数のリストが空であることを表す。

hashfunc 関数は、ハッシュ関数を表す。 search 関数、insert 関数、delete 関数は、それぞれ element 配列に対する正整数の探索、挿入、削除を行う関数である。 initarrays 関数は、hfirst 配列、element 配列、next 配列をそれぞれ初期化する関数である。 outputarrays 関数は、hfirst 配列、element 配列、next 配列をそれぞれ標準出力に出力する関数である。

プログラム A について、以下の問いに答えよ。

(1) プログラム A を実行した際に、74 行目の outputarrays 関数の呼び出しにより標準出力に出力される文字列を書け。

(2) プログラム A の 65 行目の int data[] = {1,2,3,5,7}; を int data[] = {1,2,18,19,20}; に置き換えて実行した際に、74行目の outputarrays 関数の呼び出しにより標準出力に出力される文字列を書け。

(3) data 配列に格納される正整数の集合がどのような特徴を持つときに、search 関数の実行時間が集合のサイズに対して長くなるか答えよ。

(4) (ア) と (イ) を適切な式で埋めて、delete 関数を完成させよ。

(5) プログラム A を実行した際に、78 行目の outputarrays 関数の呼び出しにより標準出力に出力される文字列を書け。ただし、プログラム A は (2) の置き換えを行っていないものとする。

プログラム A

#include <stdio.h>
#define MAXSIZE     1000
#define P           17
#define SENTINEL    -1
#define NOTFOUND    -2
int hfirst[P];
int element[MAXSIZE];
int next[MAXSIZE];
int avail = -1;
int maxnode = 0;
int hashfunc(int data) {
    return data % P;
}
int search(int h, int data) {
    int pred = -1;
    if (hfirst[h] == -1) return NOTFOUND;
    if (element[hfirst[h]] == data) return pred;
    pred = hfirst[h];
    while (next[pred] != SENTINEL) {
        if (element[next[pred]] == data) return pred;
        pred = next[pred];
    }
    return NOTFOUND;
}
void insert(int h, int data) {
    int u;
    if (avail != -1) {
        u = avail;
        avail = next[avail];
    } else {
        u = maxnode;
        maxnode = maxnode + 1;
    }
    element[u] = data;
    next[u] = hfirst[h];
    hfirst[h] = u;
}
void delete(int h, int pred) {
    int u;
    if (pred != -1) {
        u = next[pred];
        next[pred] = [ 空欄 (ア) ];
    } else {
        u = hfirst[h];
        hfirst[h] = [ 空欄 (イ) ];
    }
    next[u] = avail; avail = u;
}
void initarrays() {
    int i;
    for (i = 0; i < P; i++) { hfirst[i] = -1; }
    for (i = 0; i < MAXSIZE; i++) { element[i] =0; }
    for (i = 0; i < MAXSIZE; i++) { next[i] = SENTINEL; }
}
void outputarrays(int maxnode) {
    int i;
    for (i = 0; i < P; i++) { printf("%d,", hfirst[i]); }
    printf("\n");
    for (i = 0; i < maxnode; i++) { printf("%d,", element[i]); }
    printf("\n");
    for (i = 0; i < maxnode; i++) { printf("%d,", next[i]); }
    printf("\n");
}
int main() {
    int data[] = {1, 2, 3, 5, 7};
    int h;
    int i;
    int pred;
    initarrays();
    for (i = 0; i < 5; i++) {
        h = hashfunc(data[i]);
        if (search(h, data[i]) == NOTFOUND) insert(h, data[i]);
    }
    outputarrays(maxnode);
    h = hashfunc(1);
    pred = search(h, 1);
    if (pred != NOTFOUND) delete(h, pred);
    outputarrays(maxnode);
    return 0;
}

Kai

(1)

1
2
3
-1,0,1,2,-1,3,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1,2,3,5,7,
-1,-1,-1,-1,-1,

(2)

1
2
3
-1,2,3,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1,2,18,19,20,
-1,-1,0,1,-1,

(3)

When hash value of all elements in array "data" are same, the time complexity of function "search" is linear to the size of array "data".

(4)

  • [ 空欄 (ア) ]: next[u]
  • [ 空欄 (イ) ]: next[u]

(5)

1
2
3
-1,-1,1,2,-1,3,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1,2,3,5,7,
-1,-1,-1,-1,-1,