思路:如下图,我们可以定义两个栈,其中一个input用于实现队列的入队列的操作(就是input栈的入栈),另外一个output用于实现出队列和取队首元素的操作(就是output栈的出栈和取栈顶元素)。

当我们要出队列或者去队首元素时时,因为出队列和取队首元素要从output栈出,所以要先将input中的元素移到output中(而且谁最后入栈,就先把谁移到output中,这样一来,后入栈(后入队列)的元素,到了output栈中就是在栈底(相当于队尾)了

同理,我们需要入队列时,因为入队列操作只能从input栈顶要进行操作,所以需要将output中的元素全部都移动到input栈中。

注意:对于元素的移动,其实由于栈后进先出的特点,我们要将一个栈中的元素移到另外一个栈中,移动完成的结果总是逆序的(入一个栈中的元素为:a b c d 移动到另外一个栈后必然是:d c b a),正式由于这样的特性我们就可以通过两个栈来实现一个队列的情况。
QueueBy2Stack.h文件

#pragma once typedef char DataType;typedef struct Stack
{DataType *data;//有效元素个数int size;//表示data段内存中能容纳的元素个数int capacity;
}Stack;typedef struct Queue
{Stack input;Stack output;//队列的有效元素个数int size;
}Queue;//初始化函数
void QueueInit(Queue *queue);
//销毁函数
void QueueDestroy(Queue *queue);
//入栈函数
void QueuePush(Queue *queue,DataType value);
//出栈函数
void QueuePop(Queue *queue);
//取栈顶元素函数
int QueueFront(Queue *queue,DataType *front);

QueueBy2Stack.c文件

#include<stdio.h>
#include<stdlib.h>
#include"QueueBy2Stack.h"#define Test_Header printf("\n==========%s==========\n",__FUNCTION__);//栈初始化
void StackInit(Stack *stack)
{if(stack == NULL){//非法输入return;}stack->size = 0;stack->capacity = 1000;stack->data = (DataType*)malloc(stack->capacity * sizeof(DataType));
}
//栈销毁函数
void StackDestroy(Stack *stack)
{if(stack == NULL){//非法输入return;}free(stack->data);stack->data = NULL;stack->size = 0;stack->capacity = 0;
}
//入栈操作
void StackPush(Stack *stack,DataType value)
{if(stack == NULL){//非法输入return;}if(stack->size >= stack->capacity){//栈满了return;}//栈没满stack->data[stack->size++] = value;
}
//出栈操作
void StackPop(Stack *stack)
{if(stack == NULL){//非法输入return;}if(stack->size == 0){//空栈return;}stack->size--;
}
//取栈顶元素函数
int StackGetTop(Stack *stack,DataType *value)
{if(stack == NULL){//非法输入return 0;}if(stack->size == 0){//空栈return 0;}*value = stack->data[stack->size-1];return 1;
}//队列初始化函数
void QueueInit(Queue *queue)
{if(queue == NULL){//非法输入return;}StackInit(&queue->input);StackInit(&queue->output);queue->size = 0;
}//队列销毁函数
void QueueDestroy(Queue *queue)
{if(queue == NULL){//非法输入return;}StackDestroy(&queue->input);StackDestroy(&queue->output);queue->size = 0;
}//入队列函数
void QueuePush(Queue *queue,DataType value)
{if(queue == NULL){//非法输入return;}//将output(用于出队列的栈)中的元素倒腾到input(用于入队列的栈)中while(1){DataType front;int ret = StackGetTop(&queue->output,&front);//如果取栈顶元素返回了0,则说明output(用于出队列的栈)中已经没有元素了if(ret == 0){break;}//将output中的元素出栈StackPop(&queue->output);//将output的栈首元素插入到input中StackPush(&queue->input,front);}//倒腾完成以后再将要插入的新元素插入到input栈中StackPush(&queue->input,value);//将队列元素个数+1queue->size++;
}//出队列函数
void QueuePop(Queue *queue)
{if(queue == NULL){//非法输入return;}//将input(用于入队列的栈)中的元素倒腾到output(用于出队列的栈)中while(1){DataType front;int ret = StackGetTop(&queue->input,&front);//如果取栈顶元素返回了0,则说明该栈中已经没有元素了if (ret == 0){break;}//将input中的元素出栈StackPop(&queue->input);//将input(用于入队列的栈)中的栈顶元素插入到output(用于出队列的栈)中 StackPush(&queue->output,front);}//倒腾完成以后将output(用于出队列的栈)中的栈顶元素出栈(即出队列操作)StackPop(&queue->output);//队列元素个数-1queue->size--;
}//取队首元素函数
int QueueFront(Queue *queue,DataType *front)
{if(queue == NULL){//非法输入return 0;}//将input(用于入队列的栈)中的元素倒腾到output(用于出队列的栈)中while(1){DataType front;int ret = StackGetTop(&queue->input,&front);//如果取栈顶元素返回了0,则说明该栈中已经没有元素了if(ret == 0){break;     }//将input中的元素出栈StackPop(&queue->input);//将input(用于入队列的栈)中的栈顶元素插入到output(用于出队列的栈)中 StackPush(&queue->output,front);}//取用于出队列的栈的栈首元素(即取出队首元素)int ret = StackGetTop(&queue->output,front);return ret;
}//打印队列元素以便观察函数测试结果(其中思路不再详述,与之前函数思路一致)
void PrintQueueElem(Queue *queue,const char *msg)
{printf("[%s]\n",msg);if(queue == NULL){//非法输入return;}if(queue->size == 0){//空队列return;}while(1){DataType front;int ret = StackGetTop(&queue->output,&front);if(ret == 0){break;}StackPop(&queue->output);StackPush(&queue->input,front);}int i = 0;for(;i < queue->input.size;i++){printf("%c ",stack->data[i]);}printf("\n\n");
}
//以下为测试函数
void TestQueueBy2Stack()
{Test_Header;Queue queue;//队列初始化QueueInit(&queue);//入队列函数测试QueuePush(&queue,'a');QueuePush(&queue,'b');QueuePush(&queue,'c');QueuePush(&queue,'d');PrintQueueElem(&queue,"入队列4个元素:a b c d");//以下为取队首元素函数测试1DataType front;int ret = QueueFront(&queue,&front);printf("expected ret = 1,actual ret = %d\n",ret);printf("expected front = a,actual front = %c\n",front);//出队列函数测试QueuePop(&queue);QueuePop(&queue);PrintQueueElem(&queue,"出队列两个元素");//取队首元素测试2ret = QueueFront(&queue,&front);printf("expected ret = 1,actual ret = %d\n",ret);printf("expected front = c,actual front = %c\n",front);QueuePop(&queue);QueuePop(&queue);PrintQueueElem(&queue,"将最后两个元素也出队列");//取队首元素函数测试3(空队列)ret = QueueFront(&queue,&front);printf("expected ret = 0,actual ret = %d\n",ret);//销毁队列QueueDestroy(&queue);
}
//主函数调用测试函数
int main()
{TestQueueBy2Stack();return 0;
}

测试结果如下图:

通过两个栈实现一个队列(C语言)相关推荐

  1. 多态指针访问虚函数不能被继承的类快速排序N皇后问题插入排序堆排序merge归并排序栈上生成对象两个栈实现一个队列...

    多态 /*1. 要想实现覆盖(重写)父类必须声明为virtual,子类可以不声明为virtual.-->FunB()2. 派生类重写基类的虚函数实现多态,要求函数名.参数列表.返回值完全相同.( ...

  2. 【剑指offer】用两个栈实现一个队列

    题目:两个栈实现一个队列. 栈的特点:先进后出,队列的特点是先进先出 思路:stack1放入数据:pop时,先判断stack2是否为空,如果不为空,直接pop,如果空,则push(stack1.pop ...

  3. 剑指offer五:两个栈实现一个队列

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. package com.jianzhioffer;import java.util.Stack;publ ...

  4. 两个栈实现一个队列,两个队列实现一个栈

    题目:用两个栈实现一个队列,用两个队列实现一个栈. 首先要了解栈和队列这两种数据结构各自的特点,栈是一种后入先出(Last In First Out,LIFO)的数据结构,队列是一种先进先出(Firs ...

  5. python 用两个栈实现一个队列

    | 两个栈实现队列 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能.(若队列中没有元素 ...

  6. java实现-两个栈实现一个队列和两个队列实现一个栈

    1.两个栈实现一个队列 思路:压入元素直接入stack1,删除元素先判断stack2中是否为空,如果不为空直接弹出:为空则将stack1中的元素取出压入 stack2中再弹出. 代码: import ...

  7. python ——两个队列实现一个栈两个栈实现一个队列

    1.两个队列实现一个栈 进栈:元素入队列A 出栈:判断如果队列A只有一个元素,则直接出队.否则,把队A中的元素出队并入队B,直到队A中只有一个元素,再直接出队.为了下一次继续操作,互换队A和队B. p ...

  8. 两个栈实现一个队列与两个队列实现一个栈

    http://blog.csdn.net/z84616995z/article/details/19204529 两个栈实现一个队列: 原理方法:用一个栈为主栈,一个栈为辅助栈存放临时元素. 入队:将 ...

  9. 【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)

    http://blog.csdn.net/hanjing_1995/article/details/51539578 使用两个栈实现一个队列 思路一: 我们设定s1是入栈的,s2是出栈的. 入队列,直 ...

  10. 两个栈实现一个队列/两个队列实现一个栈

    http://blog.csdn.net/sinat_30472685/article/details/70157227 1两个栈实现一个队列 1.原理分析: 队列的主要操作有两个:入队操作和出队操作 ...

最新文章

  1. dateformat java 并发_java.text.DateFormat 多线程并发问题
  2. 优艾智合机器人科技_在全球最大工业机器人消费市场,优艾智合如何助力产业智能化?...
  3. 使用Docker Compose 部署Nexus后初次登录账号密码不正确,并且在nexus-data下没有admin.password
  4. pragma pack(1) and #pragma pack(push,1)
  5. 82.开始→运行→输入的命令集锦
  6. 数据结构实验之栈四:括号匹配
  7. vue前期知识点笔记
  8. HTML如何添加锚点,干货满满
  9. 【牛客 - 188D 】愤怒(01滚动数组优化dp,括号匹配方案个数,tricks)
  10. html 指定对象为块元素,html内联(行内)元素、块级(块状)元素和行内块元素分类...
  11. 在CDH sandbox中安装并测试livy
  12. linux系统怎么改输入法,linux系统输入法怎么切换
  13. 递归算法教学设计java,递归算法数字游戏教学软件的设计|java递归算法经典实例...
  14. Excel自动化报表制作
  15. 【BIT2021程设】2. 解谜游戏——初见DFS
  16. 推荐一个易学预测、学术研讨、资源分享网站:龙腾易学网
  17. android 设置textview 左边,Android设置图片在TextView上、下、左、右
  18. 昆石VOS2009/VOS3000 2.1.7.03 Web 接口说明
  19. 互联网晚报 | 12月1日 星期三 | 支付宝上线“支付宝小荷包”功能;快手好物联盟升级为“快分销”;小米公益平台正式上线...
  20. PTA练习:谁先倒.(C语言)

热门文章

  1. 大气压力换算公式_大气压怎么算
  2. hbase java 建表_Java在HBase数据库创建表
  3. java连接Hbase操作数据库的全过程---搭建hbase数据库
  4. java htmlelement_Java Element.outerHtml方法代码示例
  5. 永洪bi logo更换
  6. bp神经网络图像压缩原理图,bp神经网络图像分类
  7. WiFi PHY技术之自动增益控制(AGC)
  8. Apollo之Canbus模块学习总结
  9. ps使用仿制图章工具,图案图章工具
  10. ssim 算法 java实现_图像质量评价指标之 PSNR 和 SSIM