针对这个问题调试一些解决方案,对于下面的代码片段,我认为方法pop()中的逻辑是错误的,因为在执行“indexUsed--”时,空格会被连续删除,但是当删除元素时,它不一定是连续的。
如果我错了,请随时纠正我。
int stackSize = 300;
int indexUsed = 0;
int[] stackPointer = { -1, -1, -1 };
StackNode[] buffer = new StackNode[stackSize * 3];
void push(int stackNum, int value) {
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = indexUsed;
indexUsed++;
buffer[stackPointer[stackNum]] = new StackNode(lastIndex, value);
}
int pop(int stackNum) {
int value = buffer[stackPointer[stackNum]].value;
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = buffer[stackPointer[stackNum]].previous;
buffer[lastIndex] = null;
indexUsed--;
return value;
}
int peek(int stack) { return buffer[stackPointer[stack]].value; }
boolean isEmpty(int stackNum) { return stackPointer[stackNum] == -1; }
class StackNode {
public int previous;
public int value;
public StackNode(int p, int v) {
value = v;
previous = p;
}
}
答案 0 :(得分:2)
你是对的,这种方法不仅效率低,过于复杂,而且不正确。
这是一个简单的测试来证明:
StackArray stack = new StackArray();
stack.push(0, 0);
stack.push(1, 10);
System.out.println(stack.pop(0));
stack.push(1, 20);
System.out.println(stack.pop(1));
System.out.println(stack.pop(1));
产地:
Exception in thread "main" java.lang.NullPointerException
at StackArray.pop(StackArray.java:18)
堆栈数据结构通常实现为数组或单链表。链表的效率较低,因为它的元素分散在堆中,其元素也有内存开销(带指针的节点对象)。另一方面,数组更快,但它具有固定的大小,因此不能用于所有任务。
这些方法中的每一种都有其优点和缺点,但创建两种方法唯一缺点的混合方法绝对没有意义(具有固定容量和内存开销)。
如果这是一个合成任务,限制只使用一个数组来存储所有三个堆栈的元素,那么可以使用以下方法。
成对地逻辑分割数组元素。每对将代表单链表的一个节点。该对的第一个元素将保存该值,而第二个元素将是指向下一个节点的指针。
很清楚,数组可以容纳任意数量的独立单链表(只要它有足够的容量)并且你知道磁头的索引。
这个想法类似于描述中给出的方法,用于保存指向三个列表的头部的指针,但是(!)另外保持指向表示"空闲内存的列表的指针"并包括数组的所有非占用元素。最初这个"堆" list将包含数组的所有元素。当您将push
元素放入其中一个堆栈时,需要pop
中的heap
元素并使用它来创建所需堆栈的元素。当元素从堆栈中popped
时,此元素将pushed
返回堆。
答案 1 :(得分:1)
您可以从阵列的一端启动其中一个堆栈。您可以从阵列的另一端启动另一个堆栈。你可以将第三个堆叠放在中间。当其中一个侧面堆栈需要空间时,您需要移动中间堆栈。但是,我有一个免费列表帮助的另一个实现。您也可以尝试此实现:
public class ThreeStacksWithOneArray {
//This is the stack node class
class StackNode {
//This is the value of the node
int value;
//This is showing the previous node
int prev;
//This is the constructor of the class
StackNode(int value, int prev) {
this.value = value;
this.prev = prev;
}
}
//This keeps the stack nodes
private StackNode[] stackNodes = null;
private static int CAPACITY = 10;
//This keeps the top of free list
private int freeListTop = 0;
//This is the variable for the size
private int size = 0;
//These are the pointers to the three stacks
private int[] stackPointers = { -1, -1, -1 };
//This is the constructor of the main class
ThreeStacksWithOneArray() {
//Initialize the stack nodes
stackNodes = new StackNode[CAPACITY];
//initialize the free list
initFreeList();
}
//Initialize the free list
private void initFreeList() {
for (int i = 0; i < CAPACITY; i++) {
//The value of each node is 0 and it points to the next node
stackNodes[i] = new StackNode(0, i + 1);
}
}
//This is the push procedure
public void push(int stackNum, int value) throws Exception {
//Print the push information
System.out.println("Push to stack "+stackNum+" value "+value);
int freeIndex;
int currentStackTop = stackPointers[stackNum - 1];
//Find the free node
freeIndex = getFreeNodeIndex();
//Make a new node in the free index
StackNode n = stackNodes[freeIndex];
//Setting the previous node
n.prev = currentStackTop;
//Setting the value
n.value = value;
stackPointers[stackNum - 1] = freeIndex;
}
//This is the pop method
public StackNode pop(int stackNum) throws Exception {
//From which stack you want to pop. -1, since it starts from 0
int currentStackTop = stackPointers[stackNum - 1];
//This checks for stack underflow
if (currentStackTop == -1) {
throw new Exception("UNDERFLOW");
}
//Get the node as a temp node
StackNode temp = stackNodes[currentStackTop];
//Remove the node from stack
stackPointers[stackNum - 1] = temp.prev;
//Put this node as free node
freeStackNode(currentStackTop);
//Print the pop information
System.out.println("Pop from stack "+stackNum+" value: "+temp.value);
//Return the value
return temp;
}
//Get a free node index
private int getFreeNodeIndex() throws Exception {
int temp = freeListTop;
//Overflow
if (size >= CAPACITY)
throw new Exception("OVERFLOW");
freeListTop = stackNodes[temp].prev;
size++;
//return the free node index
return temp;
}
//Make one index free after a pop
private void freeStackNode(int index) {
stackNodes[index].prev = freeListTop;
//Put the index in free list
freeListTop = index;
//Decrease the size by one
size--;
}
public static void main(String args[]) {
// Test Driver
ThreeStacksWithOneArray mulStack = new ThreeStacksWithOneArray();
try {
//Adding to those three stacks
mulStack.push(1, 11);
mulStack.push(1, 12);
mulStack.push(1, 13);
mulStack.push(1, 14);
mulStack.push(2, 21);
mulStack.push(2, 22);
mulStack.push(3, 31);
mulStack.push(3, 32);
//Popping from those three stacks
mulStack.pop(1);
mulStack.pop(2);
mulStack.pop(3);
} catch (Exception e) {
e.printStackTrace();
}
}
}
有关详细信息,请访问:https://github.com/m-vahidalizadeh/foundations/blob/master/src/data_structures/ThreeStacksWithOneArray.java。我希望它有所帮助。