目录
前言:栈和队列是在顺序表和链表的延伸,如果前面的顺序表和链表你已经掌握了的话,栈和队列对你来说应该就是小菜一碟了。
1、栈
(1)栈的概念及结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
(2)栈的实现
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组尾上插入数据的代价比较小。
Stack.h
#pragma once #include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h> typedef char STDataType; typedef struct Stack { STDataType* a; int top; int capacity; }SL; //初始化 void StackInit(SL* ps); //使用后销毁 void StackDestroy(SL* ps); //入栈 void StackPush(SL* ps, STDataType x); //出栈 void StackPop(SL* ps); //判断栈空 bool StackEmpty(SL* ps); //栈的大小 int StackSize(SL* ps); //栈顶元素 STDataType StackTop(SL* ps);Stack.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Stack.h" //初始化 void StackInit(SL* ps) { assert(ps); ps->a = NULL; ps->top = 0; ps->capacity = 0; } //使用后销毁 void StackDestroy(SL* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->top = ps->capacity = 0; } //入栈 void StackPush(SL* ps, STDataType x) { assert(ps); //如果栈满增容 if (ps->top == ps->capacity) { STDataType newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity); if (tmp == NULL) { printf("realloc fail\n"); exit(-1); } else { ps->a = tmp; ps->capacity = newcapacity; } } ps->a[ps->top] = x; ps->top++; } //出栈 void StackPop(SL* ps) { assert(ps); assert(ps->top > 0); ps->top--; } //判断栈空 bool StackEmpty(SL* ps) { assert(ps); return (ps->top == 0); } //栈的大小 int StackSize(SL* ps) { assert(ps); return ps->top; } //栈顶元素 STDataType StackTop(SL* ps) { assert(ps); assert(ps->top > 0); return ps->a[ps->top-1]; }test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Stack.h" //void test() //{ // SL st; // // StackInit(&st); // StackPush(&st, 1); // StackPush(&st, 2); // //StackPush(&st, 3); // //StackPush(&st, 4); // // printf("%d\n", StackTop(&st)); // // StackPop(&st); // // StackPush(&st, 3); // StackPush(&st, 4); // // while (!StackEmpty(&st)) // { // printf("%d ", StackTop(&st)); // StackPop(&st); // } // printf("\n"); // // StackDestroy(&st); // //} bool isValid(char* s) { SL st; StackInit(&st); while (*s) { if (*s == '(' || *s == '{' || *s == '[') { StackPush(&st, *s); s++; } else { if (StackEmpty(&st)) return false; char top = StackTop(&st); StackPop(&st); if ((*s == ')' && top != '(') || (*s == ']' && top != '[') || (*s == '}' && top != '{')) { StackDestroy(&st); return false; } else { s++; } } } //栈为空,说明左括号都匹配完了 bool ret = StackEmpty(&st); StackDestroy(&st); return ret; } int main() { //test(); char a[] = { "{()}" }; bool ret = isValid(a); printf("%d", ret); return 0; }
2、队列
(1)队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
![]()
(2)队列的实现
Queue.h
#pragma once #include<stdio.h> #include<assert.h> #include<stdbool.h> #include<stdlib.h> typedef int QDataType; typedef struct QueueNode { QDataType data; struct QueueNode* next; }QNode; typedef struct Queue { QNode* head; QNode* tail; }Queue; //初始化 void QueueInit(Queue* pq); //销毁 void QueueDestroy(Queue* pq); //入队 void QueuePush(Queue* pq, QDataType x); //出队 void QueuePop(Queue* pq); //判断队空 bool QueueEmpty(Queue* pq); //队的大小 size_t QueueSize(Queue* pq); //队长 QDataType QueueFront(Queue* pq); //队尾 QDataType QueueBack(Queue* pq);Queue.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Queue.h" //初始化 void QueueInit(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; } //销毁 void QueueDestroy(Queue* pq) { assert(pq); QNode* cur = pq->head; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; } //入队 void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode = (QNode*)malloc(sizeof(QNode)); assert(newnode); newnode->data = x; newnode->next = NULL; if (pq->tail == NULL) { pq->head = pq->tail = newnode; } else { pq->tail->next = newnode; pq->tail = newnode; } } //出队 void QueuePop(Queue* pq) { assert(pq); assert(pq->head && pq->tail); if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } else { QNode* next = pq->head->next; free(pq->head); pq->head = next; } } //判断队空 bool QueueEmpty(Queue* pq) { assert(pq); //return (pq->head == NULL) && (pq->tail == NULL); return pq->head == NULL; } //队的大小 size_t QueueSize(Queue* pq) { assert(pq); QDataType size = 0; QNode* cur = pq->head; while (cur) { size++; cur = cur->next; } return size; } //队长 QDataType QueueFront(Queue* pq) { assert(pq); assert(pq->head); return pq->head->data; } //队尾 QDataType QueueBack(Queue* pq) { assert(pq); assert(pq->tail); return pq->tail->data; }Test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Queue.h" void test() { Queue q; QueueInit(&q); QueuePush(&q, 1); QueuePush(&q, 2); QueuePush(&q, 3); QueuePush(&q, 4); printf("%d\n", QueueFront(&q)); printf("%d\n", QueueBack(&q)); /*while (!QueueEmpty(&q)) { printf("%d ", QueueFront(&q)); QueuePop(&q); } printf("\n");*/ QueuePop(&q); while (!QueueEmpty(&q)) { printf("%d ", QueueFront(&q)); QueuePop(&q); } printf("\n"); QueueDestroy(&q); } int main() { test(); return 0; }
栈和队列到此结束,若想再进一步,请关注下章讲解!
我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
我正在尝试为现有队列编写消费者。RabbbitMQ在一个单独的实例中运行,名为“org-queue”的队列已经创建并绑定(bind)到一个交换器。org-queue是一个持久队列,它还有一些额外的属性。现在我需要从这个队列接收消息。我使用下面的代码来获取队列的实例conn=Bunny.newconn.startch=conn.create_channelq=ch.queue("org-queue")它抛出一个错误,指出不同的耐用属性。默认情况下,Bunny似乎使用durable=false。所以我添加了durabletrue作为参数。现在它说明了其他参数之间的区别。我是否需要指定所有参
我知道我们可以做到:sidekiq_optionsqueue:"Foo"但在这种情况下,Worker只分配给一个队列:“Foo”。我需要在特定队列中分配作业(而不是worker)。使用Resque很容易:Resque.enqueue_to(queue_name,my_job)另外,为了并发问题,我需要限制每个队列的Worker数量为1。我该怎么做? 最佳答案 您可能会使用https://github.com/brainopia/sidekiq-limit_fetch然后:Sidekiq::Client.push({'class'=>
题目描述小张买了 n 件白色的衣服,他觉得所有衣服都是一种颜色太单调,希望对这些衣服进行染色,每次染色时,他会将某种颜色的所有衣服寄去染色厂,第 i 件衣服的邮费为 ai 元,染色厂会按照小张的要求将其中一部分衣服染成同一种任意的颜色,之后将衣服寄给小张,请问小张要将 n 件衣服染成不同颜色的最小代价是多少?输入描述第一行为一个整数 n ,表示衣服的数量。第二行包括 n 个整数a1,a2...an 表示第 i 件衣服的邮费为 ai 元。(1≤n≤10^5,1≤ai≤10^9 )输出描述输出一个整数表示小张所要花费的最小代价。输入输出样例输入551321输出25 思考🤔:题意:意思是
所以我从维基百科上抓取了这段ruby代码并做了一些修改:@trie=Hash.new()defbuild(str)node=@triestr.each_char{|ch|cur=chprev_node=nodenode=node[cur]ifnode==nilprev_node[cur]=Hash.new()node=prev_node[cur]end}endbuild('dogs')puts@trie.inspect我首先在控制台irb上运行它,每次我输出node时,每次{}都会给我一个空哈希值,但当我实际调用时该函数使用参数'dogs'字符串构建,它确实有效,并输出{"d"=>
我目前有一个Rails3.0项目,使用Ruby1.9.2和Resque。我的应用程序有多个工作类和多个队列,它们是动态创建的(在运行时)。此外,有多个worker已启动,可以自由地在任何队列上工作,因为在启动时没有任何现有队列,并且无法预测它们:$COUNT=3QUEUE=*rakeresque:workers根据project的id创建队列:@queue="project_#{project.id}".to_sym对于给定的队列,他们的作业必须按顺序处理,一次处理一个。我的问题是,通过拥有多个工作人员,可以并行处理多个作业。有没有办法设置每个队列的最大worker数(为1)?有没有办
是否可以使用Amazon简单排队服务创建优先级队列?最初我找不到关于这个主题的任何内容,这就是我创建两个队列的原因。一个普通队列和一个优先队列。我正在根据我定义的规则将消息排入此队列,但在出列消息时会出现困惑。如何对队列进行长时间轮询,使我的队列组合表现得像一个优先级队列? 最佳答案 我认为您通过创建两个队列走在正确的轨道上-一个普通队列和一个优先级队列。在这种情况下,您不一定需要长时间轮询。由于优先队列中的消息优先于普通队列中的消息,您可以采用如下方法:轮询优先级队列,直到没有更多消息为止。轮询普通队列并在普通队列中的每条消息后重