第6回では,以下の項目に関して学ぶ.
スタック(stack)とは,要素を一時的に蓄積するデータ構造の一つである.要素は後入れ先出し(LIFO: Last In First Out)で行われる.よって,最後に挿入された要素が最初に取り出される.
ここでは,以下に示す構造体を用いて,整数の値を蓄積するスタックを実現したソースコード prog6-1.c
を作成する.
struct stack { int data[STACK_SIZE]; int top; };この構造体は,整数の値を配列
data[]
に格納する.data[]
に対して,top
は次に整数の値が格納される位置を指す.
スタックの例を図6.1に示す.
図6.1: スタックの例
いま,スタックを実現するために,以下に示す3つの関数を用意する.
struct stack *create_stack();
stack
に格納されている整数の値を挿入した順番に画面に表示する.void print_stack(struct stack *stack);
stack
に格納されている要素の数を取得する.int size_of_stack(struct stack *stack);
上記の3つの関数を持つprog6-1.c
を作成せよ.
本課題では,図6.1のスタックの利用例にあわせて,テスト関数test1()
がすでに用意されている.スタックの動作を検査するテストコードをprog6-1.c
に追加せよ.
課題1で作成したソースコード prog6-1.c
に対して,以下に示す4つの関数を追加したソースコード prog6-2.c
を作成する.
stack
に整数の値 value
を挿入する.挿入が成功した場合は1
,失敗した場合は 0
を 返すint push(struct stack *stack, int value);
stack
から整数の値を取り出す.スタックが空の場合は -1
を返す.int pop(struct stack *stack);
stack
から次に取り出される整数の値を取得する(整数の値は取り出さない).スタックが空の場合は -1
を返す.int peek(struct stack *stack);
stack
が空かどうかを検査する.空の場合は 1
,空でない場合は 0
を返す.int is_empty(struct stack *stack);
上記の4つの関数とテストコードを含むprog6-2.c
を作成せよ.
キュー(queue)とは,要素を一時的に蓄積するデータ構造の一つである.要素は先入れ先出し(FIFO: First In First Out)で行われる.よって,最初に挿入された要素が最初に取り出される.
ここでは,以下に示す構造体を用いて,整数の値を蓄積するキューを実現したソースコード prog6-3.c
を作成する.
struct queue { int data[QUEUE_MAX_SIZE]; int top; int rear; };この構造体は,整数の値を配列
data[]
に格納する.data[]
に対して,top
はキューの先頭の位置,rear
は次に整数の値が格納される位置を指す.
キューの例を図6.2に示す.
図6.2: キューの例
いま,キューを実現するために,以下に示す3つの関数を用意する.
struct queue *create_queue();
queue
に格納されている整数の値を挿入した順番に画面に表示する.void print_queue(struct queue *queue);
queue
に格納されている要素の数を取得する.int size_of_queue(struct queue *queue);
上記の3つの関数を持つprog6-3.c
を作成せよ.
本課題では,図6.3のキューの利用例にあわせて,テスト関数test1()
がすでに用意されている.キューの動作を検査するテストコードをprog6-3.c
に追加せよ.
課題3で作成したソースコード prog6-3.c
に対して,以下に示す4つの関数を追加したソースコード prog6-2.c
を作成する.
queue
に整数の値 value
を挿入する.挿入が成功した場合は1
,失敗した場合は 0
を 返すint enqueue(struct queue *queue, int value);
queue
から整数の値を取り出す.キューが空の場合は -1
を返す.int dequeue(struct queue *queue);
queue
から次に取り出される整数の値を取得する(整数の値は取り出さない).キューが空の場合は -1
を返す.int peek(struct queue *queue);
queue
が空かどうかを検査する.空の場合は 1
,空でない場合は 0
を返す.int is_empty(struct queue *queue);
上記の4つの関数とテストコードを含むprog6-4.c
を作成せよ.
課題4のようなキューの実現方法では,要素を格納する配列において,次に要素を挿入する位置が単調に増加する.このため,要素の挿入と取り出しを繰り返すと,要素を蓄積できる領域が足りなくなる.
これを回避するためには,キューから要素を取り出すごとに,配列に残っているすべての要素をキューの先頭側にずらせばよい.しかしながら,蓄積している要素の数が多い場合,この方法は効率が悪い.
そこで,配列内の要素をずらすことなく,キューを実現するために,リングバッファを導入する.リングバッファとは,配列の末尾がその先頭につながっているように見せかけるデータ構造である.
ここでは,以下に示す構造体を用いて,整数の値を蓄積するキューを実現したソースコード prog6-5.c
を作成する.
struct queue { int data[QUEUE_SIZE]; int top; int rear; int num; };この構造体は,整数の値をリングバッファである配列
data[]
に格納する.data[]
に対して,top
はキューの先頭の位置,rear
は次に整数の値が格納される位置を指す.num
はキューに蓄積されている要素の数を指す.
いま,リングバッファを導入したキューを実現するために,以下に示す3つの関数を用意する.
struct queue *create_queue();
queue
に格納されている整数の値を挿入した順番に画面に表示する.void print_queue(struct queue *queue);
queue
に格納されている要素の数を返す.int size_of_queue(struct queue *queue);
さらに,キューを操作する以下に示す4つの関数を用意する.
queue
に整数の値 value
を挿入する.挿入が成功した場合は1
,失敗した場合は 0
を 返すint enqueue(struct queue *queue, int value);
queue
から整数の値を取り出す.キューが空の場合は -1
を返す.int dequeue(struct queue *queue);
queue
から次に取り出される整数の値を取得する(整数の値は取り出さない).キューが空の場合は -1
を返す.int peek(struct queue *queue);
queue
が空かどうかを検査する.空の場合は 1
,空でない場合は 0
を返す.int is_empty(struct queue *queue);
上記の7つの関数とテストコードを含むprog6-5.c
を作成せよ.