2012-05-14 47 views
4

這是我的一個算法/面試問題的書發現,別人對這個幾個職位,但我仍然有一些問題,原來這裏是文本和代碼的書:使用1個數組實現3個堆棧,這個代碼能工作嗎?

implement 3 stacks using 1 array: 
Approach 2: 

在這種方法,只要陣列中有任何空閒空間,任何堆棧都可以增長。 我們依次爲堆棧分配空間,並將新塊鏈接到前一個塊。這意味着堆棧中的任何新元素都會保留指向該特定堆棧的前一個頂層元素的指針。 在這個實現中,我們面臨一個未使用空間的問題。例如,如果堆棧刪除其中的一些元素,則刪除的元素可能不一定出現在數組的末尾。那麼,在那種情況下,我們將無法使用這些新釋放的空間。 爲了克服這個缺陷,我們可以保留一個空閒列表,並且整個數組空間最初將被提供給空閒列表。對於每一次插入,我們都會從空閒列表中刪除一個條目。在刪除的情況下,我們只需將空閒單元格的索引添加到空閒列表中即可。 在這個實現中,我們可以在可變空間利用率方面具有靈活性,但是我們需要增加空間複雜度。

1 int stackSize = 300; 
2 int indexUsed = 0; 
3 int[] stackPointer = {-1,-1,-1}; 
4 StackNode[] buffer = new StackNode[stackSize * 3]; 

5 void push(int stackNum, int value) { 
6  int lastIndex = stackPointer[stackNum]; 
7  stackPointer[stackNum] = indexUsed; 
8  indexUsed++; 
9  buffer[stackPointer[stackNum]]=new StackNode(lastIndex,value); 
10 } 

11 int pop(int stackNum) { 
12 int value = buffer[stackPointer[stackNum]].value; 
13 int lastIndex = stackPointer[stackNum]; 
14 stackPointer[stackNum] = buffer[stackPointer[stackNum]].previous; 
15 buffer[lastIndex] = null; 
16 indexUsed--; 
17 return value; 
18 } 

19 int peek(int stack) { return buffer[stackPointer[stack]].value; } 

20 boolean isEmpty(int stackNum) { return stackPointer[stackNum] == -1; } 
21 
22 class StackNode { 
23 public int previous; 
24 public int value; 
25 public StackNode(int p, int v){ 
26  value = v; 
27  previous = p; 
28 } 
29 } 

我的問題是:在評判pop()方法,設置後緩衝器[lastIndex的]爲空(第15行),然後indexUsed - (線16),將所述indexUsed是空的空間的頭部? 我們把棧頂節點稱爲第一棧:S1,第二棧:S2,第三棧:S3; 如果發生了什麼: 我已經S1之後S2之前,我想彈出S1 S3推,

index: 10 11 12 13 
------------------------------- 
| ... | s1 | s2 | s3 | null | 
------------------------------- 

,如果我想要做的第一個彈出堆棧()的indexUsed現在是13 現在, 就會變成:

index:  10 11 12 13 
---------------------------------- 
| ... | null | s2 | s3 | null | 
---------------------------------- 

現在indexUsed是13--,也就是12,所以 如果我要推一個新的節點到這個陣列什麼happends, 根據push()方法,在第7行indexUsed被分配給stackPointer,並被用作向數組推送索引,是不是會覆蓋第12條目中的s3(stack3的頂層節點)?

added: 

我該如何改變它使其工作?乍一看,我會考慮實現一個布爾型[]來跟蹤存儲陣列中每個條目的使用情況,但這會耗費時間和空間。

謝謝!

+0

似乎你有足夠的信息來回答你自己的問題,不是嗎? –

+0

以及我不認爲這個代碼的工作,但許多其他人給這段代碼作爲一個「正確」的答案。我只是想確定一下。 –

+2

描述是合理的,但示例不符合它。堆棧和空閒指針的兩個單獨緩衝區在哪裏? –

回答

1

據我所知,你是正確的 - 它沒有存儲足夠的信息來指示內存中的空洞。

堆棧的一大優點是它可以分配在數組列表的頂部,而不是鏈接列表保存前一個/下一個指針的內存 - 這種實現消除了這個優點 - 這很難想象一個應用程序,這實際上是一個很好的解決方案。

0

「爲了克服這一缺陷,我們可以維持一個自由列表和整個陣列的空間起初將給予免費清單」

基本上可以保持「五·四」棧包含所有陣列的空點。該數組將在第四個堆棧已滿時初始化。每次你進入堆棧1/2/3時,你都會從第四個彈出一個。每當你從1/2/3跳出時,你都會推回到第四。這樣,你總是知道空閒插槽的位置。

+1

也許你應該添加一些示例代碼來改進你的答案 – thaJeztah