C语言用两个栈实现队列(完整版)
队列是一种 先进先出(first in - first out, FIFO)的数据结构,队列中的元素都从后端(rear)入队(push),从前端(front)出队(pop)。
实现队列最直观的方法是用链表,但在这篇文章里我会介绍另一个方法 - 使用栈。
栈是一种 后进先出(last in - first out, LIFO)的数据结构,栈中元素从栈顶(top)压入(push),也从栈顶弹出(pop)。
为了满足队列的 FIFO 的特性,我们需要用到两个栈,用它们其中一个来反转元素的入队顺序,用另一个来存储元素的最终顺序。
方法一(使用两个栈 入队 - O(n)O(n), 出队 - O(1)O(1))
算法
入队(push)思路:考虑入队的元素是先进先出,后进后出,而你的栈是后进先出,那么你最新压入的元素(后进的)应该在栈底,也就是只要保证后进后出即可
一个队列是 FIFO 的,但一个栈是 LIFO 的。这就意味着最新压入的元素必须得放在栈底。为了实现这个目的,我们首先需要把 s1 中所有的元素移到 s2 中,接着把新元素压入 s2。最后把 s2 中所有的元素弹出,再把弹出的元素压入 s1。

出队(pop)
直接从 s1 弹出就可以了,因为 s1 的栈顶元素就是队列的队首元素。同时我们把弹出之后 s1 的栈顶元素赋值给代表队首元素的 front 变量。

以上图片以及文字来自https://leetcode-cn.com/problems/implement-queue-using-stacks/solution/yong-zhan-shi-xian-dui-lie-by-leetcode/
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
//创建栈
struct Stack{
int data[maxsize];
int top;
};
typedef struct Stack MyStack;
//队列定义为双栈
typedef struct {
MyStack s1; //S1为主栈
MyStack s2; //S2为用来反转的栈
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate() {
MyQueue * tempQueue =(MyQueue *)malloc(sizeof(MyQueue));
tempQueue->s1.top = -1 ;
tempQueue->s2.top = -1 ;
return tempQueue ;
}
/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
if(obj->s1.top<maxsize)
{
while(obj->s1.top!=-1) //栈是否满
{
obj->s2.data[++(obj->s2.top)]=obj->s1.data[(obj->s1.top)--];////把S1栈中元素压入S2实现反转
}
obj->s1.data[++(obj->s1.top)]= x ; ////把push的元素压入S1栈(此时S1为空栈,因为它的元素已经全部给S2啦)
while(obj->s2.top!=-1)
{
obj->s1.data[++(obj->s1.top)]=obj->s2.data[(obj->s2.top)--];//再把S2栈中的元素全部反转压入S1
}
}
}
void show_myQueue(MyQueue * obj)
{
int temp =obj->s1.top ;
while(temp!=-1)
{
printf("%d ",obj->s1.data[temp--]);
}
printf("\n");
}
/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
if(obj->s1.top!=-1)
{
return obj->s1.data[obj->s1.top--] ;
}
// return NULL ;
}
/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
if(obj->s1.top!=-1)
{
return obj->s1.data[obj->s1.top] ;
}
// return NULL ;
}
/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
if(obj->s1.top == -1)
return true ;
return false ;
}
void myQueueFree(MyQueue* obj) {
free(obj);
}
int main()
{
int i ;
MyQueue * myQueue =NULL;
myQueue =myQueueCreate();
for(i=0;i<3;i++)
{
myQueuePush(myQueue,i);
}
show_myQueue(myQueue);
printf("出队的元素是:%d\n",myQueuePop(myQueue));
printf("此时队列内的首个的元素是:%d\n",myQueuePeek(myQueue));
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
C语言用两个栈实现队列(完整版)的更多相关文章
- 【Java】 剑指offer(8) 用两个栈实现队列
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数append ...
- 剑指Offer面试题:6.用两个栈实现队列
一.题目:用两个栈实现队列 题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 原文是使用 ...
- 剑指OFFER之用两个栈实现队列(九度OJ1512)
题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例.对于每个测试样例,第一行输入一个n(1<=n<=100 ...
- 九度OJ 1512 用两个栈实现队列 【数据结构】
题目地址:http://ac.jobdu.com/problem.php?pid=1512 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 输入: 每 ...
- 两个栈实现队列+两个队列实现栈----java
两个栈实现队列+两个队列实现栈----java 一.两个栈实现一个队列 思路:所有元素进stack1,然后所有出s ...
- Algorithm --> 两个栈实现队列和两个队列实现栈
两个栈实现队列和两个队列实现栈 队列(queue)先进先出的线性表:栈(stack)先进后出的线性表. 两个栈实现队列 法一思路: s1是入栈的,s2是出栈的. 入队列:直接压入s1即可: 出队列:如 ...
- 二、 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek)
请指教交流! package com.it.hxs.c01; import java.util.Stack; /* 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek) */ ...
- 两个队列实现栈&两个栈实现队列(JAVA)
1,两个栈实现队列 题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路:栈的特点时先进后出,队列的特点是先进先出. 若此时有两个队列stack1,st ...
- 剑指offer【05】- 用两个栈实现队列(java)
题目:用两个栈实现队列 考点:栈和队列 题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解题思路:每次psuh是时先将stack2清空放入stck1(保 ...
随机推荐
- Docker基础内容之仓库
前言 Docker提供了开放的中央仓库dockerhub,同时也允许我们使用registry搭建本地私有仓库.搭建私有仓库有如下的优点: 节省网络带宽,提升Docker部署速度,不用每个镜像从Dock ...
- Spring注解开发系列专栏
这个系列主要是讲Spring注解的使用,可以为后面SpringBoot的学习带来一定的帮助.我觉得从Spring直接过度到SpringBoot还是有点快,还是得需要一个演变的过程.从Spring开发, ...
- RT600 I2S外设介绍及应用
恩智浦的i.MX RT600是跨界处理器产品,同样也是i.MX RTxxx系列的开山之作.不同于i.MX RT1xxx系列单片机,i.MX RT600 采用了双核架构,将新一代Cortex-M33内核 ...
- kubernetes中node心跳处理逻辑分析
最近在查看一个kubernetes集群中node not ready的奇怪现象,顺便阅读了一下kubernetes kube-controller-manager中管理node健康状态的组件node ...
- EMC NW NMM to backup MS AG
To use EMC NW NMM to backup MS SQL always on database, that is a simple and safe way to protector da ...
- C++:重载前置++/--返回引用,重载后置++/--返回临时对象
标准库中iterator对++/--的重载代码如下: _Myiter& operator++() { // preincrement ++*(_Mybase *)this; return (* ...
- Centos7更改屏幕显示率
第一种,在虚拟机中安装VMwareTools,之后在虚拟机菜单栏"查看"这一项选择立即适应窗口. 第二种,修改/boot/grub2/grub.cfg配置文件,在终端输入su,输入 ...
- Linux中Hadoop的安装与配置
一.准备 1,配通网络 ping www.baidu.com 之前安装虚拟机时配过 2,关闭防火墙 systemctl stop firewalld systemctl disable firewal ...
- javascript A*算法 寻路算法 获取最短路径算法
//A算法 自动寻路 路径 class GetAutoPath{ constructor(id, map, sPos, ePos, mapArr){ //this.type = id.type; th ...
- 杭电-------2044一只小蜜蜂(C语言写)
#include<stdio.h> ] = { }; long long divide(int n) { ) { ; } ) { return a[n]; } ) + divide(n - ...