棧資料結構用於滿足資料後進先出的功能,新元素存放與取出只能在棧頂:
下面主要介紹兩種棧結構的實現方式:
鍊錶棧陣列棧
鍊錶實現
1.入棧:新增新元素(push)
在鍊錶頭部新新增元素,可以拆解為3步
示意圖如下:
2.出棧:刪除頭節點(pop)
實現**:
public class linkedstack
public linkedstack()
public boolean isempty()
public int size()
public void push(item item)
public item pop()
}
可變長陣列實現使用定長陣列實現棧結構非常簡單,以陣列末尾當做棧頂,僅需增減末尾元素表示出棧入棧即可。
問題:由於陣列是不可變資料結構,若每次增加元素就立刻建立長度加一的新陣列,則需要遍歷原陣列將所有元素複製到新陣列,代價巨大。
解決:採用lazy extension方案,當元素需要入棧,但當前陣列已滿時,新建乙個大小為原來兩倍的陣列。當棧頂元素出棧後,數量若僅佔陣列長度的1/4時,新建乙個大小為原來的1/2倍的陣列,每次新建陣列時都要遍歷原始陣列將元素複製到新陣列。
lazy extension方案原則:我們希望當新的陣列建立以後剩餘的空間和已用空間長度相等,另外在陣列收縮時希望收縮的程度比較「可觀」(比如收縮一倍空間),因此陣列收縮時選用1/4的閾值。另外乙個原因是,如果當元素數量佔陣列長度1/2時就新建乙個大小為原來1/2倍長的陣列,那麼新建陣列是滿的,一旦新元素入棧,則需立刻建立新陣列,一旦該元素出棧,程式又需要立刻收縮陣列。
實現**:
public class resizingarraystack
public boolean isempty()
public int size()
// 重建新的陣列
private void resize(int capacity)
a = copy;
}public void push(item item)
public item pop()
}
接下來從時空複雜度來分析兩者的優劣
鍊錶棧
陣列棧
無論是可變陣列棧還是鍊錶棧,其單次時間複雜度都是常數的o(1),但是可變陣列棧是平均時間複雜度,當正好需要改變陣列大小時,其單次入棧的時間複雜度為o(n)。因此不適用於對每次出入棧都要高效的場景。
從空間複雜度和記憶體利用效率來看,陣列棧擁有更好的表現,當系統僅需要平均時間複雜度為o(1)和更好的空間利用率時,可變陣列棧是更好的選擇。
乙個包含所有c 的標頭檔案的標頭檔案
include 使用和平常的標頭檔案一樣,如下 includeusing namespace std int main int a,b cin a b cout include這個標頭檔案包含以下等等c 中包含的所有標頭檔案 include include include include inclu...
c 乙個標頭檔案引用另乙個標頭檔案的類
c 乙個標頭檔案引用另乙個標頭檔案的類 c 標頭檔案相互引用,乙個 include,另乙個class c c 標頭檔案相互 include時最好是 1 在 ca.h 中 include cb.h 2 在 cb.h 中用類的前向宣告 class ca 3 最好加上標頭檔案衛士 ifndef defin...
c 乙個標頭檔案引用另乙個標頭檔案的類
c 乙個標頭檔案引用另乙個標頭檔案的類 c 標頭檔案相互引用,乙個 include,另乙個class c c 標頭檔案相互 include時最好是 1 在 ca.h 中 include cb.h 2 在 cb.h 中用類的前向宣告 class ca 3 最好加上標頭檔案衛士 ifndef defin...