資料結構-棧(通過陣列和單向連結串列實現)
Array Stack& Single Linked List Stack
概述
- 棧是一個先入後出(FILO, First In Last Out)的有序列表
- 棧的出/入操作限制只能線上性表的同一個端進行
應用場景
- 子程式的呼叫: 在跳往子程式前, 會先將下一個指令的地址存到棧中, 直到子程式執行完後再將地址取出, 回到原來的位置 如瀏覽器的後退/向前, JVM的虛擬機器棧
- 表示式的轉換(如 中綴表示式轉字尾表示式)與求值
- 二叉樹的遍歷
- 圖形的深度優先(depth-first)搜尋法
通過陣列實現
/** 定義陣列棧*/
class ArrayStack {
/** 棧大小*/
private int maxSize;
/** 通過該陣列存放資料, 模擬棧資料結構*/
private int[] stack;
/** 棧頂的 index, 初始值為-1*/
private int top = -1;
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
}
/** 棧滿*/
public boolean isFull() {
return top == maxSize - 1;
}
/** 棧空*/
public boolean isEmpty() {
return top == -1;
}
/** 入/壓棧*/
public void push(int value) {
if (isFull()) {
System.out.println("入棧失敗, 棧已滿!");
return;
}
top++;
stack[top] = value;
}
/** 出/彈棧*/
public int pop() {
if (isEmpty()) {
throw new RuntimeException("出棧失敗, 沒有資料!");
}
int value = stack[top];
top--;
return value;
}
/** 從棧頂開始列印所有內容*/
public void list() {
if (isEmpty()) {
System.out.println("列印失敗, 沒有資料!");
return;
}
for (int i = top; i >= 0; i--) {
System.out.printf("stack[%d]=%d\n", i, stack[i]);
}
}
}
public class ArrayStackApp {
public static void main(String[] args) {
System.out.println("push(新增資料到棧頂)");
System.out.println("pop(從棧取資料)");
System.out.println("show(列印棧所有內容)");
System.out.println("exit(退出程式)");
/** 建立陣列棧例項*/
ArrayStack stack = new ArrayStack(3);
String command;
boolean loop = true;
Scanner scanner = new Scanner(System.in);
while (loop) {
System.out.println("請輸入命令!");
command = scanner.next();
switch (command) {
case "show":
stack.list();
break;
case "push":
System.out.println("請輸入數值!");
int value = scanner.nextInt();
stack.push(value);
break;
case "pop":
try {
int result = stack.pop();
System.out.printf("資料 %d已出棧!\n", result);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "exit":
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程式結束!");
}
}
通過單向連結串列實現
/** 定義節點*/
class Node {
int no;
Node next;
/** 建立一個新的節點, 同時 next指向, 之前的棧頂節點*/
public Node(int no, Node next){
this.no = no;
this.next = next;
}
public int getNo() {
return no;
}
}
/** 定義不帶頭的單向連結串列棧*/
class ListStack {
/** 棧大小*/
int size;
/** 棧內有效節點個數*/
int count;
/** 棧頂節點*/
Node currentNode;
public ListStack(int size) {
this.size = size;
this.count = 0;
this.currentNode = null;
}
/** 棧滿*/
public boolean isFull() {
return count == size ? true: false;
}
/** 棧空*/
public boolean isEmpty() {
return count == 0 ? true: false;
}
/** 入/壓棧*/
public void push(int value) {
if (isFull()) {
System.out.println("入棧失敗, 棧已滿!");
return;
}
/** 新建節點, 再將它設為棧頂節點, 此節點的 next是引用了, 之前的棧頂節點*/
currentNode = new Node(value, currentNode);
/** 遞增有效節點個數*/
count++;
}
/** 出/彈棧*/
public int pop() {
if (isEmpty()) {
throw new RuntimeException("出棧失敗, 沒有資料!");
}
int no = currentNode.getNo();
/** 將當前下一個節點覆蓋當前節點*/
currentNode = currentNode.next;
/** 遞減有效節點個數*/
count--;
return no;
}
/** 列印棧頂的節點內容*/
public void peak(){
if (isEmpty()) {
System.out.println("列印失敗, 沒有資料!");
return;
}
System.out.println(currentNode.getNo());
}
/** 列印棧的所有節點內容*/
public void show(){
if (isEmpty()) {
System.out.println("列印失敗, 沒有資料!");
return;
}
Node temp = currentNode;
int i = count;
while (true) {
if (temp == null) {
return;
}
System.out.printf("stack[%d]=%d\n", i, temp.getNo());
i--;
temp = temp.next;
}
}
}
public class SingleLinkedListStackApp {
public static void main(String[] args) {
System.out.println("push(新增資料到棧頂)");
System.out.println("pop(從棧取資料)");
System.out.println("peak(列印棧頂的節點內容)");
System.out.println("show(列印棧的所有節點內容)");
System.out.println("exit(退出程式)");
/** 建立連結串列棧例項*/
ListStack stack = new ListStack(3);
String command;
boolean loop = true;
Scanner scanner = new Scanner(System.in);
while (loop) {
System.out.println("請輸入命令!");
command = scanner.next();
switch (command) {
case "push":
System.out.println("請輸入數值!");
int value = scanner.nextInt();
stack.push(value);
break;
case "pop":
try {
int result = stack.pop();
System.out.printf("資料 %d已出棧!\n", result);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "peak":
stack.peak();
break;
case "show":
stack.show();
break;
case "exit":
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程式結束!");
}
}
如果您覺得有幫助,歡迎點贊哦 ~ 謝謝!!
相關文章
- 資料結構--單連結串列(通過陣列實現)資料結構陣列
- 資料結構--陣列、單向連結串列、雙向連結串列資料結構陣列
- java實現單連結串列、棧、佇列三種資料結構Java佇列資料結構
- 資料結構之php實現單向連結串列資料結構PHP
- 資料結構-2.單向連結串列的實現資料結構
- 棧_單向連結串列
- 重溫四大基礎資料結構:陣列、連結串列、佇列和棧資料結構陣列佇列
- 資料結構(雙向連結串列的實現)資料結構
- 資料結構-雙向連結串列(Python實現)資料結構Python
- js實現資料結構--單連結串列JS資料結構
- 演算法與資料結構-連結串列((linked-list)-Java實現單向連結串列演算法資料結構Java
- 【資料結構】連結串列(單連結串列實現+詳解+原碼)資料結構
- 資料結構 - 單連結串列 C++ 實現資料結構C++
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 資料結構和演算法——Go實現單連結串列並且反轉單連結串列資料結構演算法Go
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 資料結構-單連結串列、雙連結串列資料結構
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- 畫江湖之資料結構【第一話:連結串列】單向連結串列資料結構
- 畫江湖之資料結構 [第一話:連結串列] 單向連結串列資料結構
- 資料結構——雙向連結串列資料結構
- 資料結構——單連結串列的C++實現資料結構C++
- 陣列和連結串列陣列
- go 實現單向連結串列Go
- 佇列_單向連結串列佇列
- 重學資料結構和演算法(一)之複雜度、陣列、連結串列、棧、佇列、圖資料結構演算法複雜度陣列佇列
- 025 通過連結串列學Rust之使用棧實現雙端佇列Rust佇列
- 連結串列 - 單向連結串列
- 資料結構與演算法(二)佇列、棧、連結串列資料結構演算法佇列
- 資料結構之雙向連結串列資料結構
- 用c語言實現資料結構——單連結串列C語言資料結構
- 資料結構——單連結串列介面實現(C語言)資料結構C語言
- 資料結構-js實現棧和佇列資料結構JS佇列
- 資料結構實驗之連結串列五:單連結串列的拆分資料結構
- 聊聊陣列與連結串列,棧與佇列陣列佇列
- 連結串列-單連結串列實現
- 資料結構與演算法整理總結---陣列,連結串列資料結構演算法陣列
- 資料結構之單連結串列資料結構