スタックは、先入れ後出しの順序付きリストです。制限された要素の挿入と削除は、同じ端、つまりスタックの一番上でのみ行うことができ、もう一方の端はスタックの一番下と呼ばれる固定端です。この記事では主に、スタックの配列実装と連結リスト実装を紹介します。
1 つの配列の実装
配列を使用して実装するには、まずデータを格納するための配列が必要であり、maxSize を使用して配列のサイズを表し、次に top を使用して現在スタックの一番上にある要素の添え字を表します。スタックであり、対応する要素が処理されます。初期化時に top=-1 であり、スタックが空であることを示します。
アイデアは比較的単純で、コードに直接アクセスするだけです。
package com.datastructure.stack;
public class ArrayStack implements MyStack {
private int maxSize; //栈容量
private int[] stack; //存放栈元素
private int top; //栈顶元素的下标
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack = new int[this.maxSize];
top = -1; //栈空时 top = -1
}
public boolean isFull() {
return top == maxSize - 1; //数组满了就是栈满了
}
public boolean isEmpty() {
return top == -1;
}
//push的时候先确定栈没有满
//然后top+1,并将新元素存放到该下标处
public void push (int value) {
if(isFull()) {
System.out.println("栈空间已满");
return;
}
top++;
stack[top] = value;
}
//先返回当前top所指的元素
//然后top-1,指向新的top元素所在位置
public int pop() {
if(isEmpty()) {
System.out.println("栈空");
throw new RuntimeException("栈空,无法弹出数据");
}
return stack[top--];
}
public void show() {
if(isEmpty()) {
System.out.println("栈空");
return;
}
for(int i=top; i>-1; --i) {
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
}
2 一方向連結リストの実装
各スタック要素はデータ ノードで表されます. 単純なスタック ノードには、値を格納するための値と、次の要素を格納するための next が必要です.
class StackNode {
int value; //值
StackNode next; //指向下一个节点
StackNode(int value) {
this.value = value;
this.next = null;
}
}
明確にする必要がある唯一のことは、リンクされたリストのどのノードに対応する必要があるかということです。top が満たす必要がある条件によって異なります。
- 挿入と削除が頻繁に行われるため、このノードにすばやくアクセスすることも必要です。
- 後続のノードには、最上位ノードから簡単にアクセスできます。
一方向連結リストの場合、任意の位置での挿入と削除の操作は同じですが、アクセス速度が異なり、連結リストの先頭ノードのアクセス速度の方が明らかに高速です。2 番目の条件については、ヘッド ノードのみが満たすことができます。
そこで, スタックを実装するために先頭ノードを持つ一方向連結リストを使用します. top は先頭ノードです. スタックの先頭ノードが のとき, スタックが空であることを意味します. ここでは,スタックtop.next
がtop.next == null
もちろん、スタックサイズも設定できます。
package com.datastructure.stack;
public class LinkedStack implements MyStack{
StackNode top;//top是正真top节点的前一个节点,类似于头节点
LinkedStack() {
top = new StackNode(-1);
}
//入栈
//将新节点插入到头节点后面
@Override
public void push(int value) {
if (isFull()) {
System.out.println("栈满");
return;
}
StackNode newNode = new StackNode(value);
newNode.next = top.next;
top.next = newNode;
System.out.println("新增元素:" + value);
}
//出栈
//将 top.next 指向原 top.next 的后一个节点
@Override
public int pop() {
if (isEmpty()){
System.out.println("栈空");
throw new RuntimeException("栈空,无法弹出");
}
int value = top.next.value;
top.next = top.next.next;
return value;
}
@Override
public void show() {
if(isEmpty()) {
System.out.println("栈空");
return;
}
System.out.println("当前栈为");
StackNode temp = top.next;
while (temp != null) {
System.out.println(temp.value);
temp = temp.next;
}
}
//栈空
@Override
public boolean isEmpty() {
return top.next == null;
}
//这里不设置栈大小,假设栈始终不满
@Override
public boolean isFull() {
return false;
}
}
class StackNode {
int value; //值
StackNode next; //指向下一个节点
StackNode(int value) {
this.value = value;
this.next = null;
}
}