目录

这道题给了我们两个队列,要求去实现栈;
首先,我们要知道栈和队列的特征:
栈:后进先出,只能从栈顶入数据和出数据;
队列:先进先出,从队尾入数据,队头出数据;
根据这些特点,我们可以采用两边倒的方法来实现;
具体来说:
1.入栈时就是在不为空的队列插入数据,若两个队列都为空,就随便插入到一个队列中;
2.出栈时将不为空的队列的数据倒入为空的队列中,当不为空的队列就剩一个数据时,就停止向空队列倒数据,然后再删点那最后一个数据;
3.判空时,需要两个队列都为空,才算栈为空;
4.取栈顶元素即取不为空的队列的队尾元素,在取栈顶元素前要判断栈是否为空;
5.销毁栈时,要先销毁其中的两个队列,然后再销毁栈。
因为是用C语言实现的,所以得自己手搓个队列。
typedef int Qdatatype;
typedef struct QueueNode
{
struct QueeuNode* next;
Qdatatype data;
}QueueNode;
typedef struct Queue
{
QueueNode* head;
QueueNode* tail;
}Queue;
void Queueinit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
void Queuedestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while (cur != pq->tail)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
}
void Queuepush(Queue* pq, Qdatatype x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
void Queuepop(Queue* pq)
{
assert(pq);
assert(pq->head);
QueueNode* next = pq->head->next;
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
free(pq->head);
pq->head = next;
}
}
Qdatatype Queuefront(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
Qdatatype Queueback(Queue* pq)
{
assert(pq);
assert(Queuesize(pq) > 0);
return pq->tail->data;
}
int Queuesize(Queue* pq)
{
assert(pq);
int size = 0;
QueueNode* cur = pq->head;
while (cur != pq->tail->next)
{
size++;
cur = cur->next;
}
return size;
}
bool Queueempty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
typedef struct
{
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack*obj=(MyStack*)malloc(sizeof(MyStack));
if(obj==NULL)
exit(-1);
Queueinit(&obj->q1);
Queueinit(&obj->q2);
return obj;
}
void myStackPush(MyStack* obj, int x)
{
if(!Queueempty(&obj->q1))
{
Queuepush(&obj->q1,x);
}
else
{
Queuepush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
Queue*empty=&obj->q1;
Queue*noempty=&obj->q2;
if(!Queueempty(&obj->q1))
{
empty=&obj->q2;
noempty=&obj->q1;
}
while(Queuesize(noempty)>1)
{
Queuepush(empty,Queuefront(noempty));
Queuepop(noempty);
}
int front=Queuefront(noempty);
Queuepop(noempty);
return front;
}
int myStackTop(MyStack* obj) {
if(!Queueempty(&obj->q1))
{
return Queueback(&obj->q1);
}
else
{
return Queueback(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return Queueempty(&obj->q1)&&Queueempty(&obj->q2);
}
void myStackFree(MyStack* obj) {
Queuedestroy(&obj->q1);
Queuedestroy(&obj->q2);
free(obj);
}

这个的解法和上面的类似,只不过这个不用总是来回倒;
根据栈和队列的特征,我们会发现将一个栈中的数据倒入另一个栈时,数据的顺序刚好符合队列的要求,不需要再重复地倒数据,所以我们可以让一个栈专门用来入数据(Pushst),一个栈专门用来出数据(Popst),当我们要出数据而这个栈为空时,我们才将用来入数据的栈中的数据倒入用来出数据的栈 。
如图:
1.判空时,需要两个栈都为空,队列才为空;
2.返回队头数据时,和出数据的操作类似,只是不需要删除队头的数据,还有在之前要判断队列是否为空;
3.销毁队列前,要先销毁两个栈。
同样,因为是C语言,得先手搓个栈。
#define MR_CAP 5
typedef int STdatatype;
typedef struct Stack
{
STdatatype* arr;
int top;
int capacity;
}ST;
void Stackinit(ST* ps)
{
assert(ps);
ps->arr = (STdatatype*)malloc(MR_CAP * sizeof(STdatatype));
if (ps->arr == NULL)
{
perror("Stackinit malloc");
exit(-1);
}
ps->top = 0;
ps->capacity = MR_CAP;
}
void Stackdestroy(ST* ps)
{
assert(ps);
free(ps->arr);
ps->arr = NULL;
ps->top = 0;
ps->capacity = 0;
}
void Stackpush(ST* ps, STdatatype x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STdatatype* tmp = (STdatatype*)realloc(ps->arr, ps->capacity * 2 * sizeof(STdatatype));
if (tmp == NULL)
{
perror("Stackpush realloc");
exit(-1);
}
else
{
ps->arr = tmp;
ps->capacity *= 2;
}
}
ps->arr[ps->top] = x;
ps->top++;
}
void Stackpop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
STdatatype Stacktop(ST* ps)
{
assert(ps);
return ps->arr[ps->top - 1];
}
int Stacksize(ST* ps)
{
assert(ps);
return ps->top;
}
bool Stackempty(ST* ps)
{
assert(ps);
if (ps->top == 0)
{
return true;
}
else
return false;
}
typedef struct {
ST Pushst;
ST Popst;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue*obj=(MyQueue*)malloc(sizeof(MyQueue));
if(obj==NULL)
exit(-1);
Stackinit(&obj->Pushst);
Stackinit(&obj->Popst);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
Stackpush(&obj->Pushst,x);
}
int myQueuePeek(MyQueue* obj) {
if(Stackempty(&obj->Popst))
{
while(!Stackempty(&obj->Pushst))
{
Stackpush(&obj->Popst,Stacktop(&obj->Pushst));
Stackpop(&obj->Pushst);
}
}
return Stacktop(&obj->Popst);
}
int myQueuePop(MyQueue* obj) {
int front=myQueuePeek(obj);
Stackpop(&obj->Popst);
return front;
}
bool myQueueEmpty(MyQueue* obj) {
return Stackempty(&obj->Pushst)&&Stackempty(&obj->Popst);
}
void myQueueFree(MyQueue* obj) {
Stackdestroy(&obj->Pushst);
Stackdestroy(&obj->Popst);
free(obj);
}
🐲👻这两道题的讲解就到这里了,若有错误或是建议欢迎小伙伴们指出。🐯🤖
🥰🤩希望小伙伴们可以多多支持博主哦。😍😃
😁😄谢谢你的阅读。😼😸

我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几