キューはスタックに比べて少しばかり,構造が複雑になっている.実際,それを直線的な イメージのメモリーにデータを追加しようとすると,以下のような問題が生じる.
教科書では,配列を用いたプリントキューのプログラム(p.123-125 List 4-5)を載せてい る.これも講義では説明しないので,各自,プログラムを解析せよ.
このプログラムでは,配列queue[]を使ってキューを実現している.配列 queue[]とキューの先頭を表す変数queue_firstと末尾を表す queue_lastはグローバル変数と宣言されているので,以下のキューを操作する関数 で直にアクセスすることができる.
キューを実装するための記憶領域が確保されたならば,それを操作しなくてはならない. キューの操作は2つで,データを追加することと,データを取り出すこと である.リスト2では,次の2つの関数でそれを行っている.
ここで使われているプログラムのテクニックは,すでに学習済みであるが,分かりにくい ものだけ述べておく.
2項演算子%は,割り算の結果の余りを返す.これをりようして,このプログラム では,queue_lastやqueue_firstの値を,
とサイクリック(cyclic:周期の)に変化させている.5の次の値を0にしているのである. これは,サイクリックに値を変化させて対時の常套手段である.
1 #define QUEUE_MAX 5+1 /* キューのサイズ+1 */
2 #define QUEUE_EMPTY -1
3
4 /* 配列によるキュー構造 */
5 int queue[QUEUE_MAX];
6 /* キューの先頭位置(配列先頭からのオフセット) */
7 int queue_first=0;
8 /* キューの末尾位置(配列先頭からのオフセット) */
9 int queue_last=0;
10
11 /* キューにデータを追加する */
12 void enqueue(int val)
13 {
14 /* lastの次がfirstならば */
15 if((queue_last+1)%QUEUE_MAX ==queue_first)
16 {
17 /* 現在配列の中身は,すべてキューの要素で埋まっている */
18 printf("ジョブが満杯です\n");
19 }
20 else
21 {
22 /* キューに新しい値を入れる */
23 queue[queue_last]=val;
24 /* queue_lastを1つ後ろにずらす。
25 もし,いちばん後ろの場合は,先頭にもってくる */
26 queue_last=(queue_last+1)%QUEUE_MAX;
27 }
28 }
29
30 /* キューからデータを取り出す */
31 int dequeue(void)
32 {
33 int ret;
34
35 if(queue_first==queue_last)
36 {
37 /* 現在キューは1つもない */
38 return QUEUE_EMPTY;
39 }
40 else
41 {
42 /* いちばん先頭のキューを返す準備 */
43 ret=queue[queue_first];
44 /* キューの先頭を次に移動する */
45 queue_first=(queue_first+1)%QUEUE_MAX;
46 return ret;
47 }
48 }
[転載について]
このペー
ジ中のリスト2のプログラムは,教科書として使用している以下の書籍
| 書名 | プログラミングの宝箱 アルゴリズムとデータ構造 ISBN4-7973-2419-8 |
| 著作者 | 紀平拓男・春日伸弥 |
| 出版社 | ソフトバンク パブリッシング株式会社 |