リンク スタック、つまりリンク リストは、スタック ストレージ構造を実装するために使用されます。
チェーン スタックの実装の考え方はシーケンス スタックと似ており、シーケンス スタックは数列テーブル (配列) の一方の端をスタックの底部として使用し、もう一方の端をスタックの上部として使用します。同じことがチェーン スタックにも当てはまります。通常、次の図に示すように、リンク リストの先頭をスタックの最上部として使用し、末尾をスタックの最下部として使用します。
リンク リストの先頭をスタックの最上部の一端として使用すると、データを「スタックに入れる」および「スタックから出す」操作を実装するときに、リンク リストを走査するという多くの時間のかかる操作を回避できます。
リンクされたリストの先頭はスタックの最上位として使用されます。これは次のことを意味します。
- データの「プッシュ」操作を実装する場合、データはリンクされたリストの先頭から挿入する必要があります。
- データの「ポップ」操作を実装する場合、リンク リストの先頭にあるヘッド ノードを削除する必要があります。
したがって、チェーン スタックは実際には、ヘッド補間によってのみデータを挿入または削除できる連結リストになります。
チェーンスタック要素がスタックにプッシュされます
たとえば、要素 1、2、3、および 4 を順番にスタックにプッシュすることは、ヘッド補間メソッドを使用して各要素をリンク リストに順番に追加することと同じです。各データ要素の追加プロセスを次の図に示します。
C 言語の実装コードは次のとおりです。
//链表中的节点结构
typedef struct lineStack{
int data;
struct lineStack * next;
}lineStack;
//stack为当前的链栈,a表示入栈元素
lineStack* push(lineStack * stack,int a){
//创建存储新元素的节点
lineStack * line=(lineStack*)malloc(sizeof(lineStack));
line->data=a;
//新节点与头节点建立逻辑关系
line->next=stack;
//更新头指针的指向
stack=line;
return stack;
}
チェーンスタック要素がスタックからポップアウトされる
たとえば、上記の e) に示すチェーン スタックで、要素 3 をスタックからポップする場合、「先入れ後出し」の原則に従って、最初に要素 4 をスタックからポップする必要があります。つまり、リンク リストから要素 3 を削除すると、要素 3 がスタックから外される可能性があります。全体の操作プロセスは、次の図に示されています。
したがって、チェーン スタックのスタック トップ要素を実現するための C 言語実装コードは次のとおりです。
//栈顶元素出链栈的实现函数
lineStack * pop(lineStack * stack){
if (stack) {
//声明一个新指针指向栈顶节点
lineStack * p=stack;
//更新头指针
stack=stack->next;
printf("出栈元素:%d ",p->data);
if (stack) {
printf("新栈顶元素:%d\n",stack->data);
}else{
printf("栈已空\n");
}
free(p);
}else{
printf("栈内没有元素");
return stack;
}
return stack;
}
コード内に if 判定文を使用することで、ユーザーが「スタックは空だけどデータをポップする必要がある」という誤った操作を行うことを防ぎます。
要約する
このセクションでは、ヘッド補間法を使用してデータの単一リンク リストを操作することによってチェーン スタック構造を実現します。チェーン スタックの完全なコードと C 言語での基本操作は次のとおりです。
#include <stdio.h>
#include <stdlib.h>
typedef struct lineStack{
int data;
struct lineStack * next;
}lineStack;
lineStack* push(lineStack * stack,int a){
lineStack * line=(lineStack*)malloc(sizeof(lineStack));
line->data=a;
line->next=stack;
stack=line;
return stack;
}
lineStack * pop(lineStack * stack){
if (stack) {
lineStack * p=stack;
stack=stack->next;
printf("弹栈元素:%d ",p->data);
if (stack) {
printf("栈顶元素:%d\n",stack->data);
}else{
printf("栈已空\n");
}
free(p);
}else{
printf("栈内没有元素");
return stack;
}
return stack;
}
int main() {
lineStack * stack=NULL;
stack=push(stack, 1);
stack=push(stack, 2);
stack=push(stack, 3);
stack=push(stack, 4);
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
return 0;
}
プログラムを実行した結果は次のようになります。
弹栈元素:4 栈顶元素:3
弹栈元素:3 栈顶元素:2
弹栈元素:2 栈顶元素:1
弹栈元素:1 栈已空
栈内没有元素
2023 新バージョンのデータ構造とアルゴリズム Java ビデオ チュートリアル (パート 1)、上級 Java プログラマーが学ぶべきデータ構造とアルゴリズム 2023 新バージョンのデータ構造とアルゴリズム
Java ビデオ チュートリアル (パート 2)、上級 Java プログラマーが学ぶべきデータ構造とアルゴリズム学ばなければなりません