上次文章中提到幾個習題,這裡解決一下:
r-6.3 實現乙個函式transfer(s,t)將棧s中所有元素倒置放入t。
def transfer(s, t):
while not s.is_empty():
t.push(s.pop())
還有其他解法,比較簡單。
c-6.16 修改棧的實現方法,加入乙個引數maxlen,使其大小限制在maxlen中,若超出,則丟擲乙個異常。
我的想法是在__init__中新增乙個self._maxlen和self._size,每次push前先判斷max和len的大小,在進行壓棧操作。
class arraystack:
default_len = 10
def __init__(self):
self._data =
self._maxlen = arraystack.default_len
self._size = 0
def push(self, val):
if self._maxlen <= self._size
self._size += 1
同樣地,在pop時進行一次self._size的自減。
丟擲異常的話,就不贅述了,定義乙個異常類,raise即可。
c-6.18 實現r-6.3功能使其在原棧上更改輸出。
我不知道這道題的正確解決思路是什麼,我覺得會不會是加乙個中間變數而已?希望大家能提出自己的想法。
def transfer2(s):
temp =
size = 0
while not s.is_empty():
size += 1
for i in range(size):
s.push(temp[i])
感覺中間有很多過程可以省略,水平有限,就這樣吧。
p-6.35 棧常用於「撤銷」操作,在上面的練習中我們做了乙個棧滿丟擲異常的練習,現在嘗試模擬我們真實的「撤銷」操作,即撤銷的歷史記錄是有乙個上限的,我們在達到上限(maxlen)時,將最底下的元素拋棄掉,來騰出空間。
下面考慮三種思路,第一種也是最直觀的,即拋棄掉第乙個元素,然後後面的元素依次迭代回來,我們需要乙個扔掉棧底的函式,就叫他dump吧。
def dump(self):
del(self._data[0])
self._size -= 1
簡單粗暴,必定帶來問題,就是列表元素確實是刪除了,但是其實在python內部進行了一次迭代,演算法的時間複雜度是o(n),當元素數量一旦上來了,所消耗的時間是線性增長的。
這裡考慮第二種思路,就是我給這個棧乙個頂和底的屬性,這個頂和底實際上是一種索引,頂索引到我應該壓棧到哪個位置的值、底索引到我該拋棄掉哪個位置的值,這個思路非常簡單。但是唯一的缺點就是更像是對列表進行操作而削弱了棧的壓入、彈出操作,各有千秋。
最後一種思路,是鍊錶,一旦考慮到列表的擴大、縮小,一定少不了操作上更好實現的鍊錶,用鍊錶實現這個問題會在後期鍊錶種講到。
明天開始學習佇列、雙端佇列,道理和棧差不多。
Python資料結構學習筆記(二)
python列表的底層分析 列表的內部結構 typedef struct pylistobject 列表有容量的概念,可以動態新增元素。但如果滿了,就得申請乙個更長的陣列。擴容 列表所佔記憶體大小計算 pyobject var head 24位元組 ob item 二級指標,8位元組 allocat...
資料結構學習筆記(二)
分類 順序儲存結構 順序表 鏈式儲存結構 鍊錶 比較 順序表 可以隨機訪問 占用連續空間,儲存分配只能預先進行,即靜態分配。一旦分配好了,在對其操作過程中不變 插入操作需要移動多個元素 鍊錶 不可以隨機訪問 不需要占用連續空間,動態分配。即在要建立新結點的時候再進行空間劃分。插入操作不需要移動多個元...
大話資料結構學習筆記(二)
測定執行時間最可靠的方法就是計算對執行時間有消耗的基本操作的執行次數。在評定演算法的優劣時,與最高次項相乘的常數並不重要,而與最高端項的階數有關。演算法時間複雜度 大o記法。o 1 常數階,o n 線性階,o n 2 平方階。推導大o階 1.用常數1取代執行時間中的所有加法常數 2.在修改後的執行次...