スタックのために必要な記憶領域が確保されたならば,それを操作しなくてはならない. スタックに必要な操作は2つで,データを積む(push)ことと,データを取り出す(pop)こと である.リスト1では,次の2つの関数でそれを行っている.
1 #define STACK_MAX 10 2 3 /* ※この例では,double型のデータを格納するスタックを作成 */ 4 double stack[STACK_MAX]; 5 /* スタック頂上の位置(最下部からのオフセット) */ 6 int stack_top=0; 7 8 /* スタックへpush */ 9 void stack_push(double val) 10 { 11 if(stack_top==STACK_MAX) 12 { 13 /* スタックが満杯になっている */ 14 printf("エラー:スタックが満杯です(Stack overflow)\n"); 15 exit(EXIT_FAILURE); 16 } 17 else 18 { 19 /* 渡された値をスタックに積む */ 20 stack[stack_top]=val; 21 ++stack_top; 22 } 23 } 24 25 /* スタックからデータをpop */ 26 double stack_pop(void) 27 { 28 if(stack_top==0) 29 { 30 /* スタックには何もない */ 31 printf("エラー:スタックが空なのにpopが呼ばれました" 32 "(Stack underflow)\n"); 33 exit(EXIT_FAILURE); 34 return 0; 35 } 36 else 37 { 38 /* いちばん上の値を返す */ 39 --stack_top; 40 return stack[stack_top]; 41 } 42 }
キューはスタックに比べて少しばかり,構造が複雑になっている.実際,それを直線的な イメージのメモリーにデータを追加しようとすると,以下のような問題が生じる.
このプログラムでは,配列queue[]を使ってキューを実現している.配列 queue[]とキューの先頭を表す変数queue_firstと末尾を表す queue_lastはグローバル変数と宣言されているので,以下のキューを操作する関数 で直にアクセスすることができる.
キューを実装するための記憶領域が確保されたならば,それを操作しなくてはならない. キューの操作は2つで,データを追加することと,データを取り出すこと である.リスト2では,次の2つの関数でそれを行っている.
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 }
空のスタックに対して,以下の操作を行ったとき,データ構造の様子を図で示せ.
PUSH( ) :スタックにデータ をプッシュする.戻り値は無し. POP() :スタックからデータをポップする.戻り値は,取り出した値.
PUSH(3) PUSH(5) POP() PUSH(2) PUSH(1) POP() POP() PUSH(1) POP() PUSH(7)
空のスタックやキューに対して,以下の操作を行ったとき,データ構造の 様子を図で示せ.
ENQ( ) :キューにデータ を追加する.戻り値はなし. DEQ() :キューからデータを取り出す.戻り値は取り出した値.
ENQ(6) ENQ(2) DEQ() ENQ(7) DEQ() ENQ(3) ENQ(1) ENQ(2) DEQ() DEQ()
[転載について]
このページ中のリスト1とリスト2のプログラムは,教科書として使用している以下の書籍
書名 | プログラミングの宝箱 アルゴリズムとデータ構造 ISBN4-7973-2419-8 |
著作者 | 紀平拓男・春日伸弥 |
出版社 | ソフトバンク パブリッシング株式会社 |