Java 使用单个阵列实现三个堆栈
针对这个问题的一些解决方案进行调试,对于下面的代码片段,我认为方法pop()中的逻辑是错误的,因为在执行“indexUsed--”时,空格会连续删除,但在删除元素时,它不一定是连续的 如果我错了,请随时纠正我Java 使用单个阵列实现三个堆栈,java,algorithm,Java,Algorithm,针对这个问题的一些解决方案进行调试,对于下面的代码片段,我认为方法pop()中的逻辑是错误的,因为在执行“indexUsed--”时,空格会连续删除,但在删除元素时,它不一定是连续的 如果我错了,请随时纠正我 int stackSize = 300; int indexUsed = 0; int[] stackPointer = { -1, -1, -1 }; StackNode[] buffer = new StackNode[stackSize * 3]; void push(int sta
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;
}
}
你是对的,这种方法不仅效率低下、过于复杂,而且不正确 下面是一个简单的测试来证明:
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)
堆栈数据结构通常实现为数组或单链表。链表效率较低,因为它的元素分散在堆中,而且它的元素有内存开销(带有指针的节点对象)。另一方面,数组速度更快,但它有固定的大小,因此不能用于所有任务
这两种方法各有优缺点,但创建混合方法绝对没有意义,因为这两种方法都有缺点(容量和内存开销固定)
如果这是一个合成任务,限制只使用一个数组来存储所有三个堆栈的元素,那么可以使用以下方法 在逻辑上成对拆分数组的元素。每对将代表单个链表的一个节点。该对的第一个元素将保存该值,而第二个元素将是指向下一个节点的指针 很明显,数组可以容纳任意数量的独立单链表(只要它有足够的容量),并且您知道头的索引
其思想类似于描述中给出的方法,即保持指向三个列表头的指针,但(!)还保持指向表示“空闲内存”并包含数组中所有未占用元素的列表的指针。最初,这个“堆”列表将包含数组的所有元素。当您将
元素推入其中一个堆栈时,您需要从堆中弹出元素,并使用它创建所需堆栈的元素。当元素从堆栈中弹出时,该元素将被推回到堆中。您可以从数组的一端开始一个堆栈。可以从阵列的另一端启动另一个堆栈。你可以把第三个堆栈放在中间。当其中一个侧堆栈需要空间时,需要移动中间堆栈。然而,我有另一个实现的帮助下免费列表。您还可以尝试此实现:
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();
}
}
}
public类三栈swithonearray{
//这是堆栈节点类
类堆栈节点{
//这是节点的值
int值;
//这将显示上一个节点
国际通行证;
//这是类的构造函数
StackNode(int值,int prev){
这个值=值;
this.prev=prev;
}
}
//这将保留堆栈节点
私有StackNode[]stackNodes=null;
专用静态int容量=10;
//这将保持免费列表的顶部
private int freeListTop=0;
//这是大小的变量
私有整数大小=0;
//这些是指向三个堆栈的指针
私有int[]堆栈指针={-1,-1,-1};
//这是主类的构造函数
ThreeStacksWithOneArray(){
//初始化堆栈节点
stackNodes=新StackNode[容量];
//初始化空闲列表
initFreeList();
}
//初始化空闲列表
私有void initFreeList(){
对于(int i=0;i=容量)
抛出新异常(“溢出”);
freeListTop=stackNodes[temp].prev;
大小++;
//返回空闲节点索引
返回温度;
}
//在弹出后释放一个索引
私有节点(整数索引){
stackNodes[index].prev=freeListTop;
//将索引放在自由列表中
freeListTop=索引;
//把尺寸缩小一倍
大小--;
}
公共静态void main(字符串参数[]){
//试驾
ThreeStacksWithOneArray mulStack=新的ThreeStacksWithOneArray();
试一试{
//在这三个堆栈中添加