bags,stack,queue

data type:
value : collections of object(存儲對象方式不外乎:Array和list)
operation:add remove iterate isempty
不同的數據類型具有不同的特性:比如說,Stack 後進先出 queue先進先出
在這裏插入圖片描述
modular programming:
分離實現和接口 客戶不知實現的細節,通過接口來複用基本操作;實現不需要考慮客戶的需求,只是完成基本的操作
在這裏插入圖片描述Stack:
接口:
在這裏插入圖片描述實現:(實現數據類型,就是完成類型所支持的操作)
1、使用linklist實現Stack:
linklist的實現藉助於內部類Node,Stack類定義一個棧頂指針,針對linklist來實現push、pop操作
在這裏插入圖片描述使用linklist的Stack的性能分析:
運行時間的分析:push、pop操作都很高效,running time is constant time;
內存分析:(內存分析這塊視頻還需要看看 包括教授講的這幾句話沒太理解)
在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述2、使用array實現Stack
由於Stack有可能在一些循環中被使用到,因此對於linklist的效率仍存在質疑,希望stack實現可以更高效。使用Array 存儲Stack的元素可以實現這個目的!但是在設計數據類型時,凡是使用數組來存儲元素都會有一個問題:需要提前確定數組的大小。先從確定大小的Array 入手實現Stack ,之後再來修改!
在這裏插入圖片描述在下面的實現代碼中,存在幾個問題:需要指定數組大小;棧滿卻還在做push,數組越界;棧空卻還在做pop,數組越界;loitering問題(沒太想明白)
在這裏插入圖片描述在這裏插入圖片描述
不爲數組大小的設置限制,可以在push元素前分配合適的空間再copy在push新元素。每次push前都要copy之前的元素,導致時間複雜度爲N2。雖然使用了Array ,性能還不如linklist呢。主要問題就是resize Array size的操作過於頻繁!插入n個元素,意味着resize Array size n次!爲了減少resize的次數,我們能否在分配空間的時候多分配一些?!此時,resize的操作僅當array的空間全部滿了才進行!而不是每push一次就resize!
同樣插入n個元素,我們來比較時間複雜度:第一種方法,resize 操作執行了n次 ,每次複製數組元素都需要訪問數組兩次,因此可得出時間複雜度爲quadratic time!第二次方法,resize操作進行了lgN次,進行copy時同樣需要訪問數組兩次
在這裏插入圖片描述解釋一下(2+4+8+N)中的N,插入n個元素所對應的resize次數爲lgN,起初只有一個元素做resize,需要執行的操作次數爲2,doubling size後,二個元素時需要執行操作次數爲4,4個元素執行操作次數爲8 (第三次resize),依次可得每次resize執行操作次數爲2i,若插入n個元素,需要resize lgN次!利用等比求和公式可得時間複雜度近似爲3N!
在這裏插入圖片描述
pop元素時,我們希望數組大小也可以做到動態變化!第一種想法:當數組處於半滿狀態,resize數組!如果客戶經常執行push-pop-push操作,將導致不斷resize array。
在這裏插入圖片描述
問題出在沒有找到合適resize 數組的狀態點!於是,另一種做法指出當數組處於1/4滿,則將實際的數組大小減半!

在這裏插入圖片描述
在這裏插入圖片描述stack如果有N個元素,如果數組大小==棧中元素個數,此時爲數組分配的內存空間爲8N;又如果棧元素個數j恰好是1/4 array的大小,因此數組大小爲32N。
在這裏插入圖片描述對於棧的兩種實現,我們該如何選取呢?array實現的stack平均時間複雜度低,而且佔用的內存空間相對更少,大多數情況下,push和pop很快(快於linklist stack)!但是客戶需要時時刻刻很快,array stack就不是適用了!畢竟存在着resize操作,此時應該選擇linklist stack,以一定的內存消耗來換取時間性能。
在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述queue:
在這裏插入圖片描述
1、linklist version

在這裏插入圖片描述在這裏插入圖片描述
2、array version

generic:
在之前的queue和stack實現中,我們都是針對某一個特殊的數據類型而編寫程序,但實際上我們的數據有不同的類型,這裏提出了兩種solution:使用強制類型轉換、generic編程。
強制類型轉換:
在Java中所有的類都是Object的子類,編寫stackObject類,客戶端通過強制類型轉化來特殊化stack。強制類型轉化發生在客戶端,不好!run-time error,不好!
在這裏插入圖片描述
泛型編程:通過使用類型參數來代替具體的數據類型,當發生mismatch時屬於compiler-error!
在這裏插入圖片描述
在這裏插入圖片描述對於generic array stack implement來說,Java不支持generic array ,這裏先使用Object array 在強制類型轉化爲typename 。
在這裏插入圖片描述
在這裏插入圖片描述iteration機制:
若希望實現的數據結構提供遍歷功能,可以使用Java 的iteration機制,可以不使用,但是對於不同的數據類型,客戶需要使用調用不同的方法,iteration爲客戶程序提供簡單的遍歷機制:for-each statement!
現在來修改我們之前設計的stack類:
1、implement Iterable 接口(實現返回iterator的方法)
2、添加內部類iterator(類內實現hasNext 方法和next方法 ,在hasNext 和 next方法隱蔽了不同的實現 )
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述application:
1、不同的編程語言庫都支持stack 、queue類型,但是如果不瞭解其性能,不建議使用!
2、棧的應用:
函數的調用(遞歸)

在這裏插入圖片描述計算中綴表達式,相較於我之前接觸算法來說,思路更爲簡單!直接使用兩個棧:操作數棧、操作符棧,根據操作符間的關係確定何時出棧入棧。括號的優先級高則先計算再將結果放入棧中繼續參與運算。
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章