1.用队列实现栈
import java.util.LinkedList;
import java.util.Queue;
public class MyStack {
Queue<Integer> a;
Queue<Integer> 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.用栈实现队列
class MyQueue {
ArrayDeque<Integer> a;
ArrayDeque<Integer> 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.设计循环队列
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.下列关于队列的叙述错误的是( )
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