本日は配列を用いたスタックのC++実装について学習しました。これはポインタ方式と多くの点で異なります。
ポインタ方式では、スタックの初期化時にヘッドノードを確保し、プッシュ操作では新しいノードを割り当て、ポップ操作ではノードを解放します。これらのノードはすべて最初の位置に配置され、トップ要素を取得する際にはS->next->dataを参照します。
一方で配列方式では、単一のノードのみを確保し、その構造体内部には配列の最大サイズ、スタックトップのインデックス、整数型配列を指すポインタ(新しい要素の格納や削除に使用)が含まれます。
S->topOfStack == -1 の場合、スタックは空です。 S->topOfStack == S->capacity - 1 の場合、スタックは満杯です。
1、ノードの宣言
1 struct Node
2 {
3 int capacity; // 配列の最大サイズ
4 int topOfStack; // スタックトップのインデックス。空の場合-1、要素追加時に+1される
5 int *Array; // 整数配列を指すポインタ
6 };
7 typedef struct Node stack;
2、空スタックおよび満杯スタックの判定
1 int stackArray::isEmpty(stack *S)
2 {
3 return S->topOfStack == emptyTOS;
4 }
5 int stackArray::isFull(stack *S)
6 {
7 return S->topOfStack == S->capacity - 1;
8 }
3、スタックの作成
1 stackArray::stack *stackArray::createStack(int maxElements)
2 {
3 if (maxElements < minStackSize)
4 cout << "スタックの領域が小さすぎます。maxElementsの値を増やしてください!" << endl;
5
6 stack *S;
7 S = (stack*)new(stack);
8 if (S == NULL)
9 cout << "メモリ不足!" << '\n';
10
11 S->Array = new int[maxElements];
12 if (S->Array == NULL)
13 cout << "メモリ不足!" << '\n';
14
15 S->topOfStack = emptyTOS; // スタックトップのインデックスを-1に設定して空状態とする
16 S->capacity = maxElements; // 配列の最大サイズを設定
17 makeEmpty(S);
18 return S;
19 }
5、プッシュ・トップ・ポップ操作
1 stackArray::stack *stackArray::push(stack *S)
2 {
3 if (isFull(S))
4 {
5 cout << "スタックが満杯です!" << endl;
6 return 0;
7 }
8 int x = 0;
9 cout << "プッシュするデータを入力してください:" << endl;
10 scanf_s("%d", &x);
11 S->Array[++S->topOfStack] = x;
12 return S;
13 }
14 int stackArray::top(stack *S)
15 {
16 if (isEmpty(S)) // 空チェック
17 {
18 cout << "空のスタックです!" << endl;
19 return -1;
20 }
21 else
22 return S->Array[S->topOfStack];
23 }
24 stackArray::stack *stackArray::pop(stack *S)
25 {
26 if (isEmpty(S)) // 空チェック
27 {
28 cout << "空のスタックです!" << endl;
29 return 0;
30 }
31 else
32 {
33 S->topOfStack--;
34 return S;
35 }
36 }
6、メイン関数
1 int main(int argc, char * argv[])
2 {
3 cout << '\n' << "***************************************" << '\n' << '\n';
4 cout << "スタック配列の世界へようこそ!" << '\n';
5 cout << '\n' << "***************************************" << '\n' << '\n';
6
7 int i = 1;
8 int j = 0;
9 int topElement = 0;
10 stackArray *a = new stackArray;
11 stackArray::stack *S = NULL;
12 //int x = 0;
13 while (i)
14 {
15 cout << '\n' << "***************************************" << '\n';
16 cout << " 0 : スタック終了 " << '\n';
17 cout << " 1 : スタック作成 " << '\n';
18 cout << " 2 : スタックのトップ要素を表示 " << '\n';
19 cout << " 3 : 要素をプッシュ " << '\n';
20 cout << " 4 : 要素をポップ " << '\n';
21 cout << "***************************************" << '\n';
22 cout << "上記の番号から機能を選択してください:" << '\n';
23 scanf_s("%d", &j);
24
25 switch (j)
26 {
27 case 1:
28 cout << "スタック作成開始:" << '\n';
29 S = a->createStack(5);
30 break;
31 case 2:
32 topElement = a->top(S);
33 cout << "スタックのトップ要素:" << topElement;
34 break;
35 case 3:
36 cout << "プッシュ開始:" << '\n';
37 S = a->push(S);
38 break;
39 case 4:
40 cout << "ポップ開始:" << '\n';
41 S = a->pop(S);
42 break;
43 default:
44 cout << "スタックを終了します。" << '\n';
45 a->disposeStack(S);
46 i = 0;
47 break;
48 }
49
50 }
51 return 0;
52 }
動作はポインタ方式と同等であり、詳細な説明は省略します。