栈实现队列(队列实现栈)


我们在上期学了队列的相关知识,所以我们得实际应用。那栈和队列是否可以相互实现呢?那必然是可以的。接下来我们就实际操作一下吧!

栈实现队列

我们是通过栈来实现队列的,所以我们定义一个类QueueImplByStack;并且实现队列的接口。因为我们宏观来看还是在操作队列。我们的思想就是使用两个栈来实现一个队列的进行的操作。一个是主栈,一个是暂存元素的栈。比如出队操作,我们可以先把主栈内的元素仅仅只留栈底元素,其余全部弹栈到暂存栈里面,留下的元素直接弹出则就是队首元素出队操作,然后在把暂存栈里面的元素弹栈进入到主栈中,现在的顺序就是和之间的顺序是一样的了。其余的操作的思想和出队的思想是一样的。那类里面应该定义两个ArrayStack修饰的栈A与栈B。在写一个无参构造函数默认创建两个栈。

  private ArrayStack stack1;
    private ArrayStack stack2;
    public QueueImplByStack(){
        stack1 = new ArrayStack<>();
        stack2 = new ArrayStack<>();
    }

接下来就写我们的队列操作,操作都是和我们上期学的队列操作一样。乃我们就来写一下吧。

首先是入队操作,队列的入队操作就是从队尾进行入队,和栈思想是一样的,是从栈顶进元素。

出队操作是先进行判空。然后判断栈内有效元素个数是否为一,我们出队的是队首元素就相当于栈底元素,所以得要先不断弹出栈顶元素到stack2,然后在把stack1栈顶弹出即是队首元素出队。最后不要忘了把stack2进行弹栈在入栈到stack1里面。

在查看队首元素的时候思路和删除队首元素的思路是一样的,只是在stack1最后一个元素我们不进行弹栈而是记录起来,最后在返回就是队首元素。

判空操作,清空队列,求队列有效元素个数则都是判断stack1是否为空,清空stack1,求stack1里有效元素个数。

队列迭代器函数就直接调用stack1的迭代器就可以。队列的toString函数也直接调用stack1的toString函数即可。大致思路就是这样,我们直接上代码也包括了我们的测试类。

完整代码

package p2.线性结构;

import p1.接口.Queue;

import java.util.Iterator;

//栈实现队列
public class StackToQueue {
    public static void main(String[] args) {
        QueueImplByStack queue = new QueueImplByStack<>();
        for (int i = 1;i<=10;i++){
            queue.offer(i);
        }
        System.out.println(queue);
        System.out.println(queue.size());
        queue.poll();
        System.out.println(queue);
        System.out.println(queue.element());

    }
}
class QueueImplByStack implements Queue{
    private ArrayStack stack1;
    private ArrayStack stack2;
    public QueueImplByStack(){
        stack1 = new ArrayStack<>();
        stack2 = new ArrayStack<>();
    }

    @Override
    public void offer(E element) {
        stack1.push(element);
    }

    @Override
    public E poll() {
        if (isEmpty()){
            throw  new IllegalArgumentException("stack is null");
        }
        while (stack1.size() != 1){
            stack2.push(stack1.pop());
        }
        E ret = stack1.pop();
        while (!stack2.isEmpty()){
            stack1.push(stack2.pop());
        }
        return ret;
    }

    @Override
    public E element() {
        if (isEmpty()){
            throw  new IllegalArgumentException("stack is null");
        }
        while (!(stack1.size() == 1)){
            stack2.push(stack1.pop());
        }
        E ret = stack1.peek();
        while (!stack2.isEmpty()){
            stack1.push(stack2.pop());
        }
        return ret;
    }

    @Override
    public boolean isEmpty() {
        return stack1.isEmpty();
    }

    @Override
    public void clear() {
        stack1.clear();
    }

    @Override
    public int size() {
        return stack1.size();
    }

    @Override
    public Iterator iterator() {
        return stack1.iterator();
    }

    @Override
    public String toString() {
        return stack1.toString();
    }
}

上述讲栈实现队列,而下面我们讲队列实现栈,其实思路大概一样。就是使用两个队列来实现栈。但他两个不分主次栈。哪个栈里面有元素(即就是哪个不为空)我们就对哪个进行操作。所有操作均和上面一样,只是我们这个是实现的是栈接口,重写了栈的各个操作方法。乃我们就不一一展示了,直接上代码。包括了测试类的代码哦!

package p2.线性结构;

import p1.接口.Stack;

import java.util.Iterator;

//队列实现栈
public class QueueToStack {
    public static void main(String[] args) {
        StackImplByQueue stack = new StackImplByQueue<>();
        System.out.println(stack);
        for (int i = 1; i <= 5; i++) {
            stack.push(i); //队列A
        }
        System.out.println(stack.toString());
        System.out.println(stack.pop());
        System.out.println(stack);  //队列B

    }
}
class StackImplByQueue implements Stack {
    private ArrayQueue queueA;
    private ArrayQueue queueB;

    public StackImplByQueue() {
        queueA = new ArrayQueue<>();
        queueB = new ArrayQueue<>();
    }

    @Override
    public int size() {
        if (queueA.isEmpty() && queueB.isEmpty()) {
            return 0;
        } else if (!queueA.isEmpty()) {
            return queueA.size();
        } else {
            return queueB.size();
        }
    }

    @Override
    public boolean isEmpty() {
        return queueA.isEmpty() && queueB.isEmpty();
    }

    @Override
    public void push(E element) {
        if (queueA.isEmpty() && queueB.isEmpty()) {
            queueA.offer(element);
        } else if (!queueA.isEmpty()) {
            queueA.offer(element);
        } else {
            queueB.offer(element);
        }
    }

    @Override
    public E pop() {
        if (isEmpty()) {
            return null;
        }
        E ret = null;
        if (!queueA.isEmpty()) {
            while (queueA.size() != 1) {
                queueB.offer(queueA.poll());
            }
            ret = queueA.poll();
        } else {
            while (queueB.size() != 1) {
                queueA.offer(queueB.poll());
            }
            ret = queueB.poll();
        }
        return ret;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        E ret = null;
        if (!queueA.isEmpty()) {
            while (queueA.size() != 1) {
                queueB.offer(queueA.poll());
            }
            ret = queueA.poll();
            queueB.offer(ret);
        } else {
            while (queueB.size() != 1) {
                queueA.offer(queueB.poll());
            }
            ret = queueB.poll();
            queueA.offer(ret);
        }
        return ret;
    }

    @Override
    public void clear() {
        queueA.clear();
        queueB.clear();
    }

    @Override
    public Iterator iterator() {
        if (isEmpty()) {
            return queueA.iterator();
        } else if (!queueA.isEmpty()) {
            return queueA.iterator();
        } else {
            return queueB.iterator();
        }
    }
    @Override
    public String toString() {
        if (isEmpty()) {
            return "[]";
        } else if (!queueA.isEmpty()) {
            return queueA.toString();
        } else {
            return queueB.toString();
        }
    }

}

运行结果

栈实现队列(队列实现栈)_第1张图片

你可能感兴趣的:(数据结构与算法,数据结构,栈,队列)