Java實現一個棧就這麼簡單
棧定義
棧是一種基於後進先出(LIFO)策略的集合型別。本章討論如何使用Java語言實現一個基本的棧。一個棧容器要求提供入棧操作,出棧操作,獲取棧大小和判斷棧是否為空操作。抽象資料型別可定義為:
public interface Stack- { /* * 判斷棧是否為空。 */ public boolean isEmpty(); /* * 獲取棧大小。 */ public int size(); /* * 入棧。 */ public void push(Item item); /* * 出棧。 */ public Item pop(); }
陣列實現
棧元素儲存在陣列中是一種基本的實現方式。內部定義一個陣列[]a用於存在入棧的元素,整數N儲存當前元素數量。
public class ArrayStack- implements Stack
- { /** * 儲存棧元素 */ private Item[] a = (Item[]) new Object[1]; /** * 棧元素數量 */ private int N; @Override public boolean isEmpty() { return N == 0; } @Override public int size() { return N; } @Override public void push(Item item) { a[N++] = item; } @Override public Item pop() { Item item = a[--N]; a[N] = null; return item; } }
選擇用陣列標示棧內容必須先預估棧最大容量大小。在Java中,陣列一旦建立,其大小就不能改變。在實際應用中,我們一般無法在建立棧時確定其大小。如果太小,會導致陣列越界,如果太大,則會浪費記憶體空間。因此,我們需要在入棧和出棧中動態的調整資料大小。
入棧時透過檢查棧大小N和陣列大小a.length是否相等來檢查是否能夠容納新的元素。如果沒有多餘的空間,將陣列的的長度加倍。
出棧時檢查棧大小是否小於陣列的四分之一,如果滿足則把陣列大小減半。
public class ResizingArrayStack- implements Stack
- { private Item[] a = (Item[]) new Object[1]; private int N = 0; public boolean isEmpty() { return N == 0; } public int size() { return N; } public void push(Item item) { if (N == a.length) { resize(2 * a.length); } a[N++] = item; } private void resize(int max) { Item[] temp = (Item[]) new Object[max]; System.arraycopy(a, 0, temp, 0, N); a = temp; } public Item pop() { Item item = a[--N]; a[N] = null; // 避免物件遊離 if (N > 0 && N == a.length / 4) { resize(a.length / 2); } return item; } public static void main(String[] args) { ResizingArrayStack
stack = new ResizingArrayStack(); stack.push("ye"); stack.push("c"); stack.push("l"); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); } }
陣列實現的缺點在於某些push()和pop()操作會調整陣列的大小:這項操作的耗時和棧大小成正比。為了克服這個缺點,可以採用連結串列實現棧。
連結串列實現
連結串列是一種遞迴的資料結構,它或者為空,或者指向一個節點的引用,該節點含有一個泛型的元素和一個指向另一個連結串列的結構。
節點的抽象資料型別可以表示為:
private class Node{ /** * 儲存資料 */ Item item; /** * 下一個節點引用 */ Node next; }
連結串列實現時用一個節點表示棧頂元素,整數N記錄棧大小。入棧時新節點的下一個節點引用指向原來的棧頂節點,出棧時棧頂元素指向原來棧頂元素的下一個節點。
public class LinkedStack- implements Stack
- { /** * 棧頂 */ private Node first; /** * 元素數量 */ private int N; private class Node { Item item; Node next; } @Override public boolean isEmpty() { return first == null; // or N == 0; } @Override public int size() { return N; } @Override public void push(Item item) { // 棧頂新增元素 Node oldFirst = first; first = new Node(); first.item = item; first.next = oldFirst; N++; } @Override public Item pop() { // 棧頂刪除元素 Item item = first.item; first = first.next; N--; return item; } }
在結構化儲存資料集時,連結串列是陣列的一種重要替代方式。它們各有優點和缺點,我們應該根據實際情況選擇合適的實現。
作者:葉春林
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2001/viewspace-2810623/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Netty實戰:設計一個IM框架就這麼簡單!Netty框架
- java實現棧的簡單操作Java
- Elasticsearch就這麼簡單Elasticsearch
- 堆排序就這麼簡單排序
- 泛型就這麼簡單泛型
- 快速排序就這麼簡單排序
- Java實現一個簡單的計算器Java
- 原來寫個Vue 首頁就這麼簡單Vue
- SpringMVC入門就這麼簡單SpringMVC
- 基數排序就這麼簡單排序
- 歸併排序就這麼簡單排序
- 插入排序就這麼簡單排序
- 選擇排序就這麼簡單排序
- SpringDataJPA入門就這麼簡單Spring
- 氣泡排序就這麼簡單排序
- 用java實現一個簡單的區塊鏈Java區塊鏈
- java實現一個簡單的爬蟲小程式Java爬蟲
- 用java實現一個簡單的計算器Java
- LinkedHashMap就這麼簡單【原始碼剖析】HashMap原始碼
- 策略模式原來就這麼簡單!模式
- TreeMap就這麼簡單【原始碼剖析】原始碼
- 實現一個簡單的TomcatTomcat
- List集合就這麼簡單【原始碼剖析】原始碼
- 實現一個簡單的 RESTful APIRESTAPI
- 實現一個簡單的MVVM(Compile)MVVMCompile
- 簡單的實現一個原型鏈原型
- php實現一個簡單的socketPHP
- SpringBoot獲取配置檔案,就這麼簡單。Spring Boot
- zookeeper核心之ZAB協議就這麼簡單!協議
- 聊聊UDP、TCP和實現一個簡單的JAVA UDP小DemoUDPTCPJava
- 用Java程式碼實現一個簡單的聊天室功能Java
- 如何用Java Socket實現一個簡單的Redis客戶端JavaRedis客戶端
- 實現一個簡單的 jQuery 的 APIjQueryAPI
- 動手實現一個簡單的promisePromise
- 如何實現一個簡單的以太坊?
- 用 go 實現一個簡單的 mvcGoMVC
- 實現一個簡單的虛擬DOM
- 用 Swift 實現一個簡單版 ReactSwiftReact