演算法分析與設計 - 作業1

Rainycolor發表於2024-03-18

目錄
  • 問題一
  • 問題二

問題一

給棧結構設計一個求最小值的操作,要求入棧、出棧以及求最小值均在 \(O(1)\) 完成。

考慮對棧 \(s\) 額外維護一個輔助棧 \(s'\),自底向上的第 \(i\) 個元素為棧 \(s\) 中自底向下前 \(i\) 個元素中的最小值,則查詢 \(s\) 中最小值操作即為查詢 \(s'\) 棧頂元素。

考慮在維護 \(s\) 的同時維護 \(s'\):元素 \(v\) 入棧 \(s\) 時,將 \(s'\) 棧頂元素與 \(v\) 中較小值入棧 \(s'\)\(s\) 出棧時同時將 \(s'\) 出棧即可。

只是新增了一個與原棧空間相同的棧,則空間複雜度仍為 \(O(n)\) 級別,上述所有操作僅涉及常數次比較與入出棧操作,時間複雜度為 \(O(1)\) 級別。

問題二

給出策略利用棧去完成一個序列的排序,並分析相應的效能。

在問題一中給出了查詢棧中最小值的實現方法,考慮實現一個類似選擇排序的演算法,在使用棧維護無序部分,不斷地取出此時棧中的最小值並放入有序部分的尾部。

該演算法的進行需要額外維護一個用來暫存元素的棧 \(s''\)。具體地:

  1. 首先將序列中所有元素按順序入棧。
  2. 將此時棧中最小值 \(v'\) 出棧,並放入有序部分的尾部。
  3. 不斷對 \(s\) 進行出棧操作,並將出棧的元素入棧 \(s''\) 中,直至棧 \(s\) 的棧頂元素為 \(v'\)
  4. 進行一次出棧操作將 \(v'\) 出棧,再不斷地對 \(s''\) 進行出棧操作直至棧空,並將出棧元素入棧 \(s\) 中。
  5. 重複上述步驟 2~4 直至棧空,即可求得有序序列。

需要進行 \(n\) 次取出最小值操作,每次取出最小值時都需要不斷出棧直至當前棧頂為最小值再進行入棧,元素比較與出入棧操作次數上限為當前棧的大小,則總時間複雜度為 \(O(n^2)\) 級別,當待排序序列單調遞增(已為有序狀態)時可達到時間複雜度上限。

維護了三個棧與用於儲存有序部分的資料結構,元素數量總和為序列長度的常數倍,空間複雜度 \(O(n)\) 級別。

相關文章