質問編集履歴
1
質問の編集
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,50 +1,9 @@
|
|
1
1
|
いつもお世話になっています。キューについて質問させていただきます。
|
2
|
+
エンキューだけを考えて表示させたいのですが、listqの関数でキューの中身を表示させる方法がわかりません。引数がvoidでもデータを受けとり、キューの中身を表示できるものなのでしょうか?
|
2
|
-
以下が
|
3
|
+
以下がコードです。```C言語
|
3
|
-
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
|
4
|
-
バス停で並んでいる列を考える。この場合、
|
5
|
-
一番最初に並んだ人が最初にバスに乗る。あとの人は順に前に詰める。
|
6
|
-
一番最後に並んだ人は最後にバスに乗る
|
7
|
-
このように最初に入れたデータを最初に取り出す(先入れ、先出し、First In, First Out、FIFO)形式のデータ構造をキュー(queue)と呼び、stackと共にコンピュータの基本的なデータ構造の1つである。
|
8
|
-
なお、キューには以下の性質・用語がある。
|
9
|
-
列の最後尾に並ぶ事をキューにデータを追加すると言い、エンキュー(enqueue)と呼ぶ
|
10
|
-
列の最前列の人がバスに乗り込むために列を離れる事を、キューからデータを取り出すと言い、デキュー(dequeue)と呼ぶ。この時残った列の人が順に前に詰めるように、キューの先頭がなくなった分、データは前に詰められる。
|
11
|
-
キューの長さは有限である。(バスの列のベンチを想像すると良い)
|
12
|
-
キューの長さ一杯に並んでいる状態をキューが満杯(queue full)であると言う。キューが満杯の時、更なるエンキューは出来ない。
|
13
|
-
列に誰も並んでいない状態をキューが空(queue empty)であると言う。キューが空の時、更なるデキューは出来ない。
|
14
|
-
|
15
|
-
それではこのキューをシミュレートするプログラムを作成する。なお、プログラムにはenq、deq、listqの3つの関数を作成し、使用する。mainも含んだ関数の仕様は以下の通りである。また、実行例も併せて参照し、出来る限りこの表示に合わせること。
|
16
|
-
プログラムの仕様
|
17
|
-
キューのデータは正整数とする
|
18
|
-
キューデータと(多分必要になるであろう)キューの最後尾を示す変数は各関数から見えるように外部変数とする。
|
19
|
-
マクロとして、以下を定義する
|
20
|
-
#define QLEN 5 キューの長さ
|
21
|
-
#define QEMP -1 キューが空である
|
22
|
-
#define QFUL -1 キューが満杯である
|
23
|
-
int main()
|
24
|
-
無限ループ構造とし、エンキュー、デキュー、終了の3つの操作を選択させる。
|
25
|
-
エンキューの場合はエンキューするデータの入力を行う。
|
26
|
-
それぞれの指示に従った関数を呼ぶ(「終了」を選んだ場合は終了する。)
|
27
|
-
デキューの場合は得たデータを「deQ data : xx」のように表示する。
|
28
|
-
各関数の戻り値がQFUL、QEMPの場合は、それぞれ「Q full, you should deQ first!」、「Q empty, you should enQ first!」を表示する。
|
29
|
-
キューを表示する関数listq()を呼びキューの中身を表示する。
|
30
|
-
int enq(int)
|
31
|
-
mainで読み込んだ一つの正整数を引数に貰い、それをエンキューする関数である。
|
32
|
-
上ても説明したが、エンキューとはキューの最後尾にデータを一つ追加する事である。(バスの列の最後尾に並ぶ)
|
33
|
-
戻り値は、キューが満杯でエンキュー出来なかった場合はマクロ値QFULを、それ以外の正常終了した場合は0を返す。
|
34
|
-
int deq(void)
|
35
|
-
データをデキューする関数である。
|
36
|
-
デキューとはキューの先頭のデータを取り出し、戻り値とし、更に残りのデータを順に前に詰める事である。(列の先頭の人がバスに乗り込み、列が前にずれる)
|
37
|
-
戻り値は、キューが空でデキュー出来なかった場合はマクロ値QEMPを、それ以外の正常終了した場合はデキューしたデータを返す。
|
38
|
-
void listq(void)
|
39
|
-
キューの中身を表示する関数である
|
40
|
-
表示は実行例に従う事。
|
41
|
-
表示は左端がキューの先頭、右端がキューの最後尾である。
|
42
|
-
キューが空の場合は「Queue empty」の表示を行う。
|
43
|
-
キューが満杯の場合はデータを表示した後、「Queue full」の表示を行う。
|
44
|
-
大雑把な処理のテンプレートを以下に示す。
|
45
|
-
|
46
4
|
コード
|
47
5
|
```
|
6
|
+
|
48
7
|
#include <stdio.h>
|
49
8
|
#include <stdlib.h>
|
50
9
|
|
@@ -53,99 +12,6 @@
|
|
53
12
|
#define QFUL -1
|
54
13
|
|
55
14
|
int enq(int);
|
56
|
-
int deq(void);
|
57
|
-
void listq(void);
|
58
|
-
|
59
|
-
/* キューに使用する配列、その他外部変数の宣言 */
|
60
|
-
|
61
|
-
int main(){
|
62
|
-
|
63
|
-
while(1){
|
64
|
-
|
65
|
-
/* 処理の入力 */
|
66
|
-
/* 入力に従って関数を呼ぶ */
|
67
|
-
/* なお、enq()の場合は呼ぶ前に引数入力 */
|
68
|
-
/* deq()の場合は呼んだ後にデータ出力 */
|
69
|
-
/* 終了の場合はexit()を呼ぶ */
|
70
|
-
|
71
|
-
}
|
72
|
-
return 0;
|
73
|
-
}
|
74
|
-
|
75
|
-
void listq(void){
|
76
|
-
|
77
|
-
/* キューが空なら"Queue empty!\n"表示 */
|
78
|
-
/* 空じゃない場合は並んでいる個数分データ表示 */
|
79
|
-
}
|
80
|
-
|
81
|
-
int enq(int data){
|
82
|
-
|
83
|
-
/* キューが満杯ならQFULをreturn*/
|
84
|
-
/* そうでないならキューの最後尾にdataを追加 */
|
85
|
-
}
|
86
|
-
|
87
|
-
int deq(void){
|
88
|
-
|
89
|
-
/* キューが空ならQEMPをreturn*/
|
90
|
-
/* そうでないならキューの最前列のdataを変数に入れ */
|
91
|
-
/* 後続のデータを一つづつ前に移動させ、変数の値をリターンする */
|
92
|
-
}
|
93
|
-
|
94
|
-
注:各関数の変数宣言は省略してある
|
95
|
-
(提出ファイル名:prog04.c)
|
96
|
-
実行例
|
97
|
-
% a.out (右側の注意書きは実際には表示されない)
|
98
|
-
1 = enQ/2 = deQ/else = end ==> 1 ←エンキューをします
|
99
|
-
Enter enQ data ==> 1 ←エンキューデータは「1」です
|
100
|
-
Queue : 1 ←キューには今エンキューした1のみが入っています
|
101
|
-
1 = enQ/2 = deQ/else = end ==> 1
|
102
|
-
Enter enQ data ==> 2 ←エンキューデータは「2」
|
103
|
-
Queue : 1 2 ←キューには今エンキューした2が最後尾に入りました
|
104
|
-
1 = enQ/2 = deQ/else = end ==> 1
|
105
|
-
Enter enQ data ==> 3
|
106
|
-
Queue : 1 2 3
|
107
|
-
1 = enQ/2 = deQ/else = end ==> 1
|
108
|
-
Enter enQ data ==> 4
|
109
|
-
Queue : 1 2 3 4
|
110
|
-
1 = enQ/2 = deQ/else = end ==> 1
|
111
|
-
Enter enQ data ==> 5
|
112
|
-
Queue : 1 2 3 4 5 Queue full! ←キューが満杯になりました
|
113
|
-
1 = enQ/2 = deQ/else = end ==> 1
|
114
|
-
Enter enQ data ==> 6
|
115
|
-
Q full, you should deQ first! ←キューが満杯になった状態で更にエンキューしようとするとメッセージが出ます
|
116
|
-
Queue : 1 2 3 4 5 Queue full!
|
117
|
-
1 = enQ/2 = deQ/else = end ==> 2 ←デキューします
|
118
|
-
deQ data : 1 ←キューの先頭にいた1が取り出されました
|
119
|
-
Queue : 2 3 4 5
|
120
|
-
1 = enQ/2 = deQ/else = end ==> 2
|
121
|
-
deQ data : 2
|
122
|
-
Queue : 3 4 5
|
123
|
-
1 = enQ/2 = deQ/else = end ==> 2
|
124
|
-
deQ data : 3
|
125
|
-
Queue : 4 5
|
126
|
-
1 = enQ/2 = deQ/else = end ==> 2
|
127
|
-
deQ data : 4
|
128
|
-
Queue : 5
|
129
|
-
1 = enQ/2 = deQ/else = end ==> 2
|
130
|
-
deQ data : 5 ←5を取り出した時点でキューは空になりました
|
131
|
-
Queue empty!
|
132
|
-
1 = enQ/2 = deQ/else = end ==> 2
|
133
|
-
Q empty, you should enQ first! ←更にデキューしようとするとメッセージが出ます。
|
134
|
-
Queue empty!
|
135
|
-
1 = enQ/2 = deQ/else = end ==> 3 ←終了します。
|
136
|
-
%
|
137
|
-
|
138
|
-
|
139
|
-
エンキューだけを考えて表示させたいのですが、引数を必要としないvoidの関数で、データを表示することができません。データはenqの関数に入っているのはわかるのですが、それを使ってデータを表示するにはどうすればいいですか?以下が自分のコードです。
|
140
|
-
コード
|
141
|
-
```#include <stdio.h>
|
142
|
-
#include <stdlib.h>
|
143
|
-
|
144
|
-
#define QLEN 5
|
145
|
-
#define QEMP -1
|
146
|
-
#define QFUL -1
|
147
|
-
|
148
|
-
int enq(int);
|
149
15
|
//int deq(void);
|
150
16
|
void listq(void);
|
151
17
|
|