栈的概念练习

1.用队列实现栈

栈的概念练习_第1张图片

import java.util.LinkedList;
import java.util.Queue;

public class MyStack {
    Queue a;
    Queue b;
    public MyStack(){
        a = new LinkedList<>();
        b = new LinkedList<>();
    }
    public void push(int x){
        if(!a.isEmpty()){
            a.offer(x);
        }else if(!b.isEmpty()){
            b.offer(x);
        }else{
            a.offer(x);
        }
    }
    public int pop(){
        if(empty()){
            return -1;
        }
        if(!a.isEmpty()){
            int size = a.size();
            for (int i = 0; i < size - 1; i++) {
                b.offer(a.poll());
            }
            return a.poll();
        }else  {
            int size = b.size();
            for (int i = 0; i < size - 1; i++) {
                a.offer(b.poll());
            }
            return b.poll();
        }

    }


    public int top(){
        if(empty()){
            return -1;
        }if(!a.isEmpty()){
            int size = a.size();
            int val = 0;
            for (int i = 0; i < size; i++) {
                 val = a.poll();
                 b.offer(val);
            }
            return val;
        }else{
            int size = b.size();
            int val = 0;
            for (int i = 0; i < size; i++) {
                val = b.poll();
                a.offer(val);
            }
            return val;
        }
    }
    public boolean empty(){
        return a.isEmpty() && b.isEmpty();
    }

}

 2.用栈实现队列

栈的概念练习_第2张图片

 

 class MyQueue {
    ArrayDeque a;
    ArrayDeque b;
    public MyQueue() {
        a = new ArrayDeque<>();
        b = new ArrayDeque<>();
    }

    public void push(int x) {
        a.push(x);
    }

    public int pop() {
        if(b.isEmpty()){
            while(!a.isEmpty()){
              b.push(a.pop());
            }
        }
        return b.pop();
    }

    public int peek() {
        if(b.isEmpty()){
            while(!a.isEmpty()){
                b.push(a.pop());
            }
        }
        return b.peek();
    }

    public boolean empty() {
        return a.isEmpty() && b.isEmpty();
    }
}

3.设计循环队列

栈的概念练习_第3张图片

 class MyCircularQueue {
    public int front;
    public int rear;
    public int[] elem;


    public MyCircularQueue(int k) {
        elem = new int[k + 1];
    }
//入栈
    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }
        elem[rear] = value;
        rear = (rear + 1) % elem.length;
        return true;
    }
//出队列
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }
        front = (front + 1) % elem.length;
        return true;
    }

    public int Front() {
        if(isEmpty()){
            return -1;
        }
        return elem[front];
    }

    public int Rear() {
        if (isEmpty()) {
            return -1;
        }
        int index = (rear == 0) ? elem.length - 1 : rear - 1;
        return elem[index];
    }

    public boolean isEmpty() {
        return rear == front;
    }

    public boolean isFull() {
        return (rear + 1) % elem.length == front;
    }
}

栈的概念练习_第4张图片 

 4.下列关于队列的叙述错误的是( )

A.队列可以使用链表实现

B.队列是一种"先入先出"的数据结构

C.数据出队列时一定只影响队尾引用

D.数据入队列时一定从尾部插入

答案:C

A正确:队列是尾插头删,就适合使用链表实现

B正确:队列的特性

C错误:如果队列中只有一个元素时,出队列后队尾和队头引用都会影响

D正确:队列的特性 

故选择C

 

5. 下列关于用栈实现队列的说法中错误的是( )

A.用栈模拟实现队列可以使用两个栈,一个栈模拟入队列,一个栈模拟出队列

B.每次出队列时,都需要将一个栈中的全部元素导入到另一个栈中,然后出栈即可

C.入队列时,将元素直接往模拟入队列的栈中存放即可

D.入队列操作时间复杂度为O(1)

答案:B

选项B中,一个栈模拟入队列,一个栈模拟出队列,出队列时直接弹出模拟出队列栈的栈顶元素,当该栈为空时,将模拟入队列栈中所有元素导入即可,不是每次都需要导入元素,故错误

选项A中,栈和队列的特性是相反的,一个栈实现不了队列

选项C中,一个栈模拟入队列,一个栈模拟出队列,入队列时,将元素直接往模拟入队列的栈中存放

选项D中,入队列就是将元素放到栈中,因此时间复杂度就是O(1)

 

6.下面关于栈和队列的说法中错误的是( )

A.队列和栈通常都使用链表实现

B.队列和栈都只能从两端插入、删除数据

C.队列和栈都不支持随机访问和随机插入

D.队列是“先入先出”,栈是“先入后出”

 答案:AB

A错误:是尾部插入和删除,一般使用顺序表实现,队列是头部删除尾部插入,一般使用链表实现

B错误:栈是后进先出,尾部插入和删除;队列是先进先出,尾部插入头部删除

C正确:栈只能访问栈顶元素,不支持随机访问,队列也不支持

D正确:栈和队列的特性

故错误的是A和B

7. 下列关于顺序结构实现循环队列的说法,正确的是( )

A.循环队列的长度通常都不固定

B.直接用队头和队尾在同一个位置可以判断循环队列是否为满

C.通过设置计数的方式可以判断队列空或者满

D.循环队列是一种非线性数据结构

答案:C

队列适合使用链表实现,使用顺序结构(即固定的连续空间)实现时会出现假溢出的问题,因此大佬们设计出了循环队列,循环队列就是为了解决顺序结构实现队列假溢出问题的

A错误:循环队列的长度都是固定的

B错误:队头和队尾在同一个位置时 队列可能是空的,也可能是满的,因此无法判断

C正确:设置计数即添加一个字段来记录队列中有效元素的个数,如果队列中有效元素个数等于空间总大小时队列满,如果队列中有效元素个数为0时队列空

D错误:循环队列也是队列的一种,是一种特殊的线性数据结构

故选择C

 

8.现有一循环队列,其队头为front,队尾为rear(rear指向队尾数据的下一个位置),循环队列长度为N,最多存储N-1个数据。其队内有效长度为( )

A.(rear - front + N) % N + 1

B.(rear - front + N) % N

C.(rear - front) % (N + 1)

D.(rear - front + N) % (N - 1)

答案:B

解析: 

有效长度一般是rear-front, 但是循环队列中rear有可能小于front,减完之后可能是负数,所以需要+N,此时结果刚好是队列中有效元素个数,但如果rear大于front,减完之后就是有效元素个数了,再加N后有效长度会超过N,故需要%N。  

 

 9.下述有关栈和队列的区别,说法错误的是?

A.栈是限定只能在表的一端进行插入和删除操作。

B.队列是限定只能在表的一端进行插入和在另一端进行删除操作。

C.栈和队列都属于线性表

D.栈的插入操作时间复杂度都是o(1),队列的插入操作时间复杂度是o(n)

答案:D

A正确:参考栈的概念

B正确:参考队列的概念

C正确:栈和队列都是特殊的线性表,因为线性表可以在任意位置插入或者删除,但是栈和队列就没有,相当于栈和队列属于阉割版的线性表

D错误:栈和队列插入、删除操作的时间复杂度都是O(1)

故选择D

你可能感兴趣的:(java,算法,开发语言)