Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用单个阵列实现三个堆栈_Java_Algorithm - Fatal编程技术网

Java 使用单个阵列实现三个堆栈

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

针对这个问题的一些解决方案进行调试,对于下面的代码片段,我认为方法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;
    }
}

你是对的,这种方法不仅效率低下、过于复杂,而且不正确

下面是一个简单的测试来证明:

    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();
试一试{
//在这三个堆栈中添加