Example005

题目

Q 是一个队列,S 是一个空栈,实现将队列中的元素逆置的算法。

分析

主要考查对队列和栈的特性与操作。由于对队列的一系列操作不可能将其中的元素全部逆置,而栈可以将入栈的元素逆序提取出来,因此我们可以让队列中的元素逐个出队列,一一入栈;全部入栈后再逐个入栈,一一入队列。

图解

C实现

核心代码:

/*** 逆置队列中的所有元素,假设栈的空间足够大* @param Q 装了元素的队列* @param S 空栈*/
void inversionQueue(SeqQueue *Q, SeqStack *S) {// 1.先将队列 Q 中所有元素压入栈 S 中while (!isEmptyQueue(*Q)) {// 如果队列不为空,则一直将元素出队// 局部变量,记录出队元素int ele;// 将队头元素出队deQueue(Q, &ele);// 将队头元素压入栈中push(S, ele);}// 2.再将栈 S 中所有元素重新入队,即完成逆置while (!isEmptyStack(*S)) {// 如果栈不为空,则一直将元素出栈// 局部变量,记录栈顶元素int top;// 将栈顶元素出栈pop(S, &top);// 再将栈顶元素入队enQueue(Q, top);}
}

完整代码:

/*
Q 是一个队列,S 是一个空栈,实现将队列中的元素逆置的算法。
*/#include<stdio.h>/*** 顺序队列中能存储的最大元素个数*/
#define QUEUE_MAXSIZE 10/*** 顺序队列结构体定义*/
typedef struct {/*** 数据域,存储队列中的数据*/int data[QUEUE_MAXSIZE];/*** 指针域,队头指针。在空队列中,队头指针指向 0;在非空队列中,队头指针始终指向队头元素*/int front;/*** 指针域,队尾指针。在空队列中,队尾指针指向 0;在非空队列中,队尾指针始终指向队尾元素的下一位置*/int rear;
} SeqQueue;/*** 初始化顺序队列* @param queue 未初始化的顺序队列*/
void initQueue(SeqQueue *queue) {// 初始化顺序队列,将队头指针和队尾指针都指向 0// 有些实现中将队头指针和队尾指针指向 -1,这无所谓,只要能够实现队列功能即可queue->front = 0;queue->rear = 0;
}/*** 判断顺序队列是否为空* @param queue 顺序队列* @return 如果顺序队列为空则返回 1,否则返回 0 表示非空队列*/
int isEmptyQueue(SeqQueue queue) {// 如果队头指针和队尾指针都指向同一位置,则表示队列处于空// 因为队头指针和队尾指针在不断变化,只要它们相等就表示是空队列,其中 front 和 rear 可能是 0,有可能是 4,而非一直都初始化值if (queue.front == queue.rear) {return 1;} else {return 0;}
}/*** 将元素入队,即插入到队尾* @param queue 顺序队列* @param ele 待入队的元素* @return 如果入队成功则返回 1,否则返回 0 表示入队失败*/
int enQueue(SeqQueue *queue, int ele) {// 0.参数校验,如果队满,则不能入队if (queue->rear == QUEUE_MAXSIZE) {return 0;}// 1.将元素入队// 1.1 先进行赋值,初始时队头指针指向 0queue->data[queue->rear] = ele;// 1.2 然后将队尾指针加一queue->rear++;// 1.3 返回 1 表示入队成功return 1;
}/*** 将元素出队,即出队队头元素* @param queue 顺序队列* @param ele 用来保存出队元素* @return 如果出队成功则返回 1,否则返回 0 表示出队失败*/
int deQueue(SeqQueue *queue, int *ele) {// 0.参数校验,如果队空则不能出队if (queue->front == queue->rear) {return 0;}// 1.将元素出队// 1.1 用 ele 保存队头元素*ele = queue->data[queue->front];// 1.2 将队头指针加一,表示删除队头元素,使得队头指针始终指向队头元素queue->front++;// 1.3 返回 1 表示出队成功return 1;
}/*** 打印顺序队列中从队头到队尾的所有元素* @param queue 顺序队列*/
void printQueue(SeqQueue queue) {printf("[");for (int i = queue.front; i < queue.rear; i++) {printf("%d", queue.data[i]);if (i != queue.rear - 1) {printf(", ");}}printf("]\n");
}/*** 顺序栈最大存储的元素个数*/
#define STACK_MAXSIZE 100/*** 顺序栈结构体定义*/
typedef struct {/*** 数据域,数组,用来存储栈中元素*/int data[STACK_MAXSIZE];/*** 指针域,表示栈顶指针,实际上就是数组下标*/int top;
} SeqStack;/*** 初始化顺序栈,即将栈顶指针指向 -1 表示空栈* @param stack 顺序栈*/
void initStack(SeqStack *stack) {// 设定让栈顶指针指向 -1 表示为栈空stack->top = -1;
}/*** 判断顺序栈是否为空* @param stack 顺序栈* @return 如果顺序栈为空则返回 1,否则返回 0*/
int isEmptyStack(SeqStack stack) {// 只需要判断栈顶指针是否等于 -1 即可,如果是空栈则返回 1,不是空栈则返回 0if (stack.top == -1) {return 1;} else {return 0;}
}/*** 将元素入栈* @param stack 顺序栈* @param ele 元素值* @return 如果栈满则返回 0 表示入栈失败;如果插入成功则返回 1*/
int push(SeqStack *stack, int ele) {// 1.参数校验,如果栈满则不能入栈元素if (stack->top == STACK_MAXSIZE - 1) {// 如果栈满,则返回 0,表示不能入栈return 0;}// 2.先将栈顶指针加一,指向新空数组位置stack->top++;// 3.将新元素值填充到新位置中stack->data[stack->top] = ele;return 1;
}/*** 将元素出栈* @param stack 顺序栈* @param ele 用来保存出栈的元素* @return 如果栈空则返回 0 表示出栈失败;否则返回 1 表示出栈成功*/
int pop(SeqStack *stack, int *ele) {// 1.参数校验,栈空不能出栈if (stack->top == -1) {// 栈空,没有元素可出栈return 0;}// 2.用 ele 来保存顺序栈栈顶元素*ele = stack->data[stack->top];// 3.然后栈顶指针减一,表示出栈一个元素stack->top--;return 1;
}/*** 逆置队列中的所有元素,假设栈的空间足够大* @param Q 装了元素的队列* @param S 空栈*/
void inversionQueue(SeqQueue *Q, SeqStack *S) {// 1.先将队列 Q 中所有元素压入栈 S 中while (!isEmptyQueue(*Q)) {// 如果队列不为空,则一直将元素出队// 局部变量,记录出队元素int ele;// 将队头元素出队deQueue(Q, &ele);// 将队头元素压入栈中push(S, ele);}// 2.再将栈 S 中所有元素重新入队,即完成逆置while (!isEmptyStack(*S)) {// 如果栈不为空,则一直将元素出栈// 局部变量,记录栈顶元素int top;// 将栈顶元素出栈pop(S, &top);// 再将栈顶元素入队enQueue(Q, top);}
}int main() {// 声明一个队列并初始化SeqQueue queue;initQueue(&queue);// 为队列添加一些测试数据enQueue(&queue, 11);enQueue(&queue, 22);enQueue(&queue, 33);enQueue(&queue, 44);enQueue(&queue, 55);// 声明一个栈并初始化为空栈SeqStack stack;initStack(&stack);// 打印逆置前的队列printQueue(queue);// 调用函数逆置队列元素inversionQueue(&queue, &stack);// 打印逆置后的队列printQueue(queue);
}

执行结果:

[11, 22, 33, 44, 55]
[55, 44, 33, 22, 11]

Java实现

核心代码:

    /*** 逆置队列** @param Q 队列* @param S 空栈* @throws Exception 如果顺序栈已满再入栈则会抛出异常*/public static void inversionQueue(CircularQueue Q, SeqStack S) throws Exception {// 1.先将队列 Q 中所有元素压入栈 S 中while (!Q.isEmpty()) {// 如果队列不为空,则一直将元素出队// 局部变量,记录出队元素int ele;// 将队头元素出队ele = Q.deQueue();// 将队头元素压入栈中S.push(ele);}// 2.再将栈 S 中所有元素重新入队,即完成逆置while (!S.isEmpty()) {// 如果栈不为空,则一直将元素出栈// 局部变量,记录栈顶元素int top;// 将栈顶元素出栈top = S.pop();// 再将栈顶元素入队Q.enQueue(top);}}

完整代码:

public class Test {public static void main(String[] args) throws Exception {// 声明一个队列并初始化CircularQueue queue = new CircularQueue();queue.init();// 为队列添加一些测试数据queue.enQueue(11);queue.enQueue(22);queue.enQueue(33);queue.enQueue(44);queue.enQueue(55);// 声明一个栈并初始化为空栈SeqStack stack = new SeqStack();stack.init();// 打印逆置前的队列queue.print();// 调用函数逆置队列元素inversionQueue(queue, stack);// 打印逆置后的队列queue.print();}/*** 逆置队列** @param Q 队列* @param S 空栈* @throws Exception 如果顺序栈已满再入栈则会抛出异常*/public static void inversionQueue(CircularQueue Q, SeqStack S) throws Exception {// 1.先将队列 Q 中所有元素压入栈 S 中while (!Q.isEmpty()) {// 如果队列不为空,则一直将元素出队// 局部变量,记录出队元素int ele;// 将队头元素出队ele = Q.deQueue();// 将队头元素压入栈中S.push(ele);}// 2.再将栈 S 中所有元素重新入队,即完成逆置while (!S.isEmpty()) {// 如果栈不为空,则一直将元素出栈// 局部变量,记录栈顶元素int top;// 将栈顶元素出栈top = S.pop();// 再将栈顶元素入队Q.enQueue(top);}}
}

CircularQueue

public class CircularQueue {/*** 循环队列中能存储的最大元素个数*/private final int MAXSIZE = 7;/*** 声明循环队列*/private Queue queue;/*** 初始化循环队列*/public void init() {queue = new Queue();// 为数据域分配存储空间queue.data = new int[MAXSIZE];// 循环队列初始时,队头指针和队尾指针仍然都指向 0,表示是空队列queue.front = 0;queue.rear = 0;}/*** 判断循环队列是否为空** @return 如果循环队列为空则返回 true,否则返回 false 表示非空*/public boolean isEmpty() {// 只要队头指针和队尾指针相等,那么表示循环队列为空,无论指针在哪个位置return queue.rear == queue.front;}/*** 判断循环队列是否已满** @return 如果循环队列已满则返回 true,否则返回 false 表示队列非满*/public boolean isFull() {// 队尾指针再加上一,然后对 MAXSIZE 取余,如果等于队头指针,那么表示队满return (queue.rear + 1) % MAXSIZE == queue.front;}/*** 将元素入队** @param ele 指定元素* @throws Exception 如果循环队列已满则不能入队,则抛出此异常*/public void enQueue(int ele) throws Exception {// 0.参数校验,如果队满则不能入队if (isFull()) {throw new Exception("队列已满不能入队!");}// 1.将元素入队// 1.1 先进行赋值,即将新元素填充到队尾指针指向的位置。因为队尾指针指向队尾元素的下一个位置queue.data[queue.rear] = ele;// 1.2 然后将队尾指针加一。因为是循环队列,如果到了队尾,那么又要从 0 开始,所以加一后需要对 MAXSIZE 进行取余queue.rear = (queue.rear + 1) % MAXSIZE;}/*** 将元素出队** @return 出队的元素* @throws Exception 如果队空则不能出队,则抛出此异常*/public int deQueue() throws Exception {// 0.参数校验,如果队空则不能出队if (isEmpty()) {throw new Exception("队列为空不能出队!");}// 1.将队头元素出队// 1.1 用 ele 保存队头指针所指向的元素int front = queue.data[queue.front];// 1.2 将队头指针加一,表示删除队头元素。因为是循环队列,所以要对 MAXSIZE 取余queue.front = (queue.front + 1) % MAXSIZE;// 1.3 返回队头元素return front;}/*** 获取循环队列中的元素个数** @return 队列中的元素个数*/public int size() {// 如果是顺序队列,则元素个数是 rear-front// 如果是循环队列,则元素个数是 (rear-front+MAXSIZE)%MAXSIZEreturn (queue.rear - queue.front + MAXSIZE) % MAXSIZE;}/*** 获取循环队列的队头元素** @return 循环队列的队头元素* @throws Exception 如果队列为空则抛出此异常*/public int getFront() throws Exception {// 0.参数校验,如果队列为空则没有队头元素,自然无法获取,所以抛出异常表示获取失败if (isEmpty()) {throw new Exception("队空不能获取队头元素!");}// 1.返回队头元素,即队头指针所指向的元素return queue.data[queue.front];}/*** 获取循环队列中的队尾元素** @return 循环队列的队尾元素* @throws Exception 如果队列为空则抛出此异常*/public int getRear() throws Exception {// 0.参数校验,如果队列为空则没有队尾元素,自然无法获取,所以抛出此异常表示获取失败if (isEmpty()) {throw new Exception("队空不能获取队尾元素!");}// 1.返回队尾元素,由于队尾指针指向队尾元素的下一个位置,所以要队尾指针减一return queue.data[(queue.rear - 1 + MAXSIZE) % MAXSIZE];}/*** 清空循环队列*/public void clear() {// 即将队头指针和队尾指针都指向 0,表示恢复循环队列的初始状态,即空表queue.front = 0;queue.rear = 0;}/*** 打印循环队列中从队头到队尾的所有元素*/public void print() {System.out.print("[");int front = queue.front;while (front != queue.rear) {System.out.print(queue.data[front]);if (front != (queue.rear - 1 + MAXSIZE) % MAXSIZE) {System.out.print(", ");}front = (front + 1) % MAXSIZE;}System.out.print("]\n");}
}/*** 循环队列定义*/
class Queue {/*** 数据域,存储循环队列中的数据*/int[] data;/*** 指针域,存储循环队列中队头元素的位置*/int front;/*** 指针域,存储循环队列中队尾元素的位置*/int rear;
}

SeqStack

public class SeqStack {/*** 常量,顺序栈所能容纳的最大元素个数*/private final int MAXSIZE = 100;/*** 声明一个顺序栈*/private Stack stack;/*** 初始化顺序栈*/public void init() {// 实例化栈对象stack = new Stack();// 为数据域分配空间stack.data = new int[MAXSIZE];// 将顺序栈的栈顶指针指向 -1 表示空栈stack.top = -1;}/*** 判断顺序栈是否为空** @return 如果顺序栈为空则返回 true,否则返回 false*/public boolean isEmpty() {// 规定了 -1 表示空栈,所以只需要判断栈顶指针是否等于 -1 即可return stack.top == -1;}/*** 将指定元素入栈** @param ele 指定元素* @throws Exception 如果栈满则不能入栈,抛出此异常*/public void push(int ele) throws Exception {// 1.参数校验,如果栈满则不能入栈,抛出异常if (stack.top == MAXSIZE - 1) {// 因为栈顶指针 top 存储的是数组下标,所以判断是否等于 MAXSIZE-1throw new Exception("栈已满,不能再插入!");}// 2.先栈顶指针加 1,因为原栈顶指针处已经存储了元素,所以加一指向新的空位置stack.top++;// 3.在新的空位置处插入新元素,即为指定下标的数组元素赋值stack.data[stack.top] = ele;}/*** 将栈顶元素出栈** @return 栈顶元素* @throws Exception 如果栈空则不能出栈,抛出此异常*/public int pop() throws Exception {// 1.参数校验,如果栈空则不能出栈,抛出异常if (stack.top == -1) {// 因为栈空的定义是栈顶指针为 -1,所以如果栈顶指针为 -1 那么就是空栈,就不能出栈元素throw new Exception("栈为空,不能出栈元素!");}// 2.记录栈顶元素,因为要将该元素返回,即要出栈的元素int result = stack.data[stack.top];// 3.栈顶指针减一,因为原栈顶元素已经出栈了,栈中元素个数减一stack.top--;return result;}/*** 获取栈顶元素,但不出栈** @return 栈顶元素* @throws Exception 如果栈空则不能出栈,抛出此异常*/public int getTop() throws Exception {// 1.参数校验,如果栈空则不能出栈,抛出异常if (stack.top == -1) {throw new Exception("栈为空,不能获取栈顶元素!");}// 2.直接返回栈顶元素,但不出栈return stack.data[stack.top];}/*** 顺序栈中元素个数** @return 栈中元素个数*/public int size() {// top 表示栈顶指针,实际上就是数组 data 的下标,所以实际元素个数就是下标加一// 即使是空栈 top=-1,那么最后也会返回 0 表示元素个数为零个return stack.top + 1;}/*** 打印顺序栈中所有元素,从栈顶到栈底*/public void print() {System.out.print("[");for (int i = stack.top; i >= 0; i--) {if (i != stack.top) {System.out.print(", ");}System.out.print(stack.data[i]);}System.out.print("]\n");}/*** 清空顺序栈*/public void clear() {// 直接将栈顶指针指向 -1 即可表示空栈,不用重置栈中已有元素的值,因为顺序栈操作只跟栈顶指针有关stack.top = -1;}
}/*** 栈定义*/
class Stack {/*** 顺序栈用来存储元素的数组*/int[] data;/*** 记录顺序栈的栈顶指针,即数组下标*/int top;
}

执行结果:

[11, 22, 33, 44, 55]
[55, 44, 33, 22, 11]

队列练习之Example005-Q 是一个队列,S 是一个空栈,实现将队列中的元素逆置的算法相关推荐

  1. 利用栈和队列将队列中的元素逆置☆

    题目:有一个队列和一个栈,设计一个算法是队列中的元素逆置. 分析:         我们可以一次取出队列中的元素放到栈中,然后在依次取出入队. 代码: struct Stack {int* arr; ...

  2. 将栈S中的元素逆置,使用额外的一个栈L和非数组变量

    /*将栈S中的元素逆置,使用额外的一个栈L和非数组变量*/ #include<stdio.h> #include<stdlib.h> #include<time.h> ...

  3. c语言编写队列元素逆置,数据结构与算法实验—利用栈逆置队列元素.doc

    数据结构与算法实验-利用栈逆置队列元素 利用栈逆置队列元素实验报告 通信1204班 谢崇赟 实验名称 利用堆栈将队列中的元素逆置 实验目的 会定义顺序栈和链栈的结点类型. 掌握栈的插入和删除结点在操作 ...

  4. 第5周作业(杨辉三角形,队列元素逆置,银行排队——队列,整数划分问题,买票问题——卡特兰数,小兔的棋盘——卡特兰数)

    一.杨辉三角形 [问题描述]杨辉三角形的打印,请用循环队列实现.不采用"循环队列",不给分. [样例输入] 4 [样例输出] 1 1 1 1 2 1 1 3 3 1 #includ ...

  5. java---编写一个方法,返回一个int型的二维数组,数组中的元素通过解析字符串参数获得。

    题目: 编写一个方法,返回一个int型的二维数组,数组中的元素通过解析字符串参数获得,字符串如下"1,2:3,4,5:6,7"对应的数组为: d[0][0]=1 d[0][1]=2 ...

  6. 编写一个方法,将数组传入进去之后将数组中的元素反转

    public class Demo08 {     /*      需求:编写一个方法,将数组传入进去之后将数组中的元素反转. 例:传入[1,2,3] 反转:[3,2,1]      */     p ...

  7. 试编写一个将双向循环链表逆置的算法_图解:链表的快慢指针,解决 80% 的链表面试题!...

    一.前言 链表是基本的数据结构之一,它与数组不同,数组在内存中存储,需要一块连续的内容空间来存储,对内存的要求比较高.例如我们需要 100MB 大小的数组,内存中就必须有一段连续的 100MB 的内存 ...

  8. 试编写一个将双向循环链表逆置的算法_循环双向链表在电路计算中的应用

    问题描述在电路分析中,通常以图论为数学工具,进行建模,求解.我们只研究二端元件,可以将电路中的每一个元件用一条边来表示,元件的端点用顶点来表示. 元件的端点和端点是可以连接在一起的,比如导线的端点连接 ...

  9. 设计一个高效算法,将顺序表的所有元素逆置,要求算法空间复杂度为O(1)。

    void ReverseList(SqList *L) {while(i<length||i>=0){if(j=0;j<(length-1)/2;j++){a=L->data[ ...

最新文章

  1. Paging Library使用及原理
  2. dBm与Vpp相互转换公式
  3. Ruby之Rspec的报错解决
  4. 算法导论 c语言,算法导论 之 堆排序[C语言]
  5. 解决Keepalived脚本启动时warning、Unsafe
  6. maven-antrun-plugin - Target
  7. 常用JQuery插件整理
  8. 小数点进位 oracle,使用多个小数点(。)对Oracle中的记录进行排序
  9. 删除表数据有两种方法及区别
  10. python book118_Python3 book118.com文档下载(图片形式)
  11. 微信小程序 服务器代理转发,微信小程序转发功能
  12. 中国智能家居企业出海,亚马逊云科技为其提供“GPS锦囊”
  13. 我是怎么学英语的(四级没过如何突破听说读写)
  14. Java程序员的重启人生-1.初到异世界
  15. RK3288获取摄像头的Sensor ID【原创】
  16. jquery实现轮播图,可点击左右切换
  17. 光耦p621引脚图_常见光电耦合器(光耦)的内部结构及引脚图
  18. SNMP 原理与实战详解
  19. 洛谷P4925 [1007]Scarlet的字符串不可能这么可爱(计数)
  20. 中国垃圾分类产业链现状动态及未来发展前景预测报告(2022-2027年)

热门文章

  1. D2RQ平台之本体操作
  2. python 如何爬虫wind api数据_Python网络爬虫实战之十:利用API进行数据采集
  3. NoesisGUI入门及初步使用感想
  4. Stern-Brocot树 (生成0-1之间的所有真分数)
  5. 数据分析案例:APP热点标签分析
  6. 【计算机网络】ARP协议工作原理
  7. java一个式子开根号语句_[基础篇]-基础知识整理-03-JAVA中的运算符
  8. 地下城英雄 java_英雄小组
  9. 燕文物流完成上市辅导:董事长周文兴持股30%,曾因丢失邮件被批
  10. 这可能是最完整的进藏攻略