Java 使用1个数组实现3个堆栈,这段代码行吗?
这是我在一本算法/采访问题书上发现的,其他人在这本书上发表了几篇文章,但我仍然有一些问题,这是书中的原始文本和代码:Java 使用1个数组实现3个堆栈,这段代码行吗?,java,algorithm,Java,Algorithm,这是我在一本算法/采访问题书上发现的,其他人在这本书上发表了几篇文章,但我仍然有一些问题,这是书中的原始文本和代码: implement 3 stacks using 1 array: Approach 2: 在这种方法中,只要阵列中有任何可用空间,任何堆栈都可以增长。 我们依次为堆栈分配空间,并将新块链接到前一块。这意味着堆栈中的任何新元素都会保留指向该特定堆栈上一个顶部元素的指针。 在这个实现中,我们面临一个未使用空间的问题。例如,如果堆栈删除其某些元素,则删除的元素可能不一定出现在数组的
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 }
我的问题是:在mothod pop()中,在将buffer[lastIndex]设置为null(第15行)之后,然后索引--(第16行),被索引的将是空空间的头部吗?
让我们调用第一个堆栈的堆栈顶部节点:S1,第二个堆栈:S2,第三个堆栈:S3;
如果:
在我想弹出s1之前,先推s1,然后再推s2和s3
index: 10 11 12 13
-------------------------------
| ... | s1 | s2 | s3 | null |
-------------------------------
指数化的现在是13。
现在如果我想在第一个堆栈上执行pop(),
它将成为:
index: 10 11 12 13
----------------------------------
| ... | null | s2 | s3 | null |
----------------------------------
指数化的现在是13-,也就是12,
如果我想把一个新节点推到这个数组上会发生什么,
根据push()方法,在第7行,indexUsed被分配给stackPointer,并用作将索引推送到数组上,这不会覆盖第12个条目中的s3(stack3的顶部节点)吗
added:
我该如何改变它使其工作?
乍一看,我会考虑实现一个boolean[]来跟踪存储阵列中每个条目的使用情况,但这会耗费时间和空间
谢谢 据我所知,你是对的——它没有存储足够的信息来显示内存中的漏洞 堆栈的一大优势是,它可以在数组列表的顶部分配,而不是在链表上分配,从而节省了上一个/下一个指针的内存——这种实现消除了这种优势——很难想象在应用程序中这是一个好的解决方案。“为了克服这一缺陷,我们可以维护一个空闲列表,整个数组空间最初将分配给空闲列表”
基本上你可以保持“第四”“堆栈,其中包含阵列的所有空点。该数组将在第四个堆栈已满时初始化。每次推入堆栈1/2/3时,都会从第四个堆栈中弹出一个堆栈。每次你从1/2/3跳出来,你都会把它推回第四位。通过这种方式,您总是知道免费插槽在哪里。似乎您有足够的信息来回答自己的问题,不是吗?我认为这段代码不起作用,但许多其他人将这段代码作为“正确”的答案给出。我只是想确定一下。描述是合理的,但示例与之不符。堆栈和自由指针的两个独立缓冲区在哪里?难道你不能运行它来找出答案吗?编辑后,可能会编写一些单元测试:不要使用布尔[],而是在堆栈数组中使用带有布尔和指针的链表。嗯,在重新考虑之后,列表中元素的顺序并不重要,所以一个带有指针的LinkedList就足够了。或者是一个布尔[]和一个指向最后一个元素的长度int。也许你应该添加一些示例代码来改进你的答案