第24课 - 队列的特别实现

讨论:

A: 重新实现的方式确实提高了顺序队列和链式队列的效率,可是实现过程还是比较复杂的。

B: 这也是没有办法的事,直接复用链表虽然可以实现队列,但是效率不好。

C: 有没有既能复用之前的代码,又能高效实现队列。

1. 思路

准备两个栈用于实现队列:inStack和outStack

当有新元素入队时:将其压入inStack

当需要出队时:
         当outStack为空时:

将inStack中的元素逐一弹出并压入outStack中。

将outStack的栈顶元素弹出。

当outStack不为空时:

直接将outStack的栈顶元素弹出。

2. 算法框架

Append(queue,node)

{

Push(inStack,node);

}

Retrieve(queue)

{

if(Size(outStack) == 0)

{

while(Size(inStack)>0)

{

Push(outStack,Pop(inStack));

}

}

return Pop(outStack);

}

3. 程序

main.c

#include <stdio.h>

#include <stdlib.h>

#include "SQueue.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[])

{

SQueue* queue = SQueue_Create();

int a[10] = {0};

int i = 0;

for(i=0; i<10; i++)

{

a[i] = i + 1;

SQueue_Append(queue, a + i);

}

printf("Header: %d\n", *(int*)SQueue_Header(queue));

printf("Length: %d\n", SQueue_Length(queue));

for(i=0; i<5; i++)

{

printf("Retrieve: %d\n", *(int*)SQueue_Retrieve(queue));

}

printf("Header: %d\n", *(int*)SQueue_Header(queue));

printf("Length: %d\n", SQueue_Length(queue));

for(i=0; i<10; i++)

{

a[i] = i + 1;

SQueue_Append(queue, a + i);

}

while( SQueue_Length(queue) > 0 )

{

printf("Retrieve: %d\n", *(int*)SQueue_Retrieve(queue));

}

SQueue_Destroy(queue);

return 0;

}

LinkList.c

LinkList.h

LinkStack.h

#ifndef _LINKSTACK_H_

#define _LINKSTACK_H_

typedef void LinkStack;

LinkStack* LinkStack_Create();

void LinkStack_Destroy(LinkStack* stack);

void LinkStack_Clear(LinkStack* stack);

int LinkStack_Push(LinkStack* stack, void* item);

void* LinkStack_Pop(LinkStack* stack);

void* LinkStack_Top(LinkStack* stack);

int LinkStack_Size(LinkStack* stack);

#endif

LinkStack.c

#include <malloc.h>

#include "LinkStack.h"

#include "LinkList.h"

typedef struct _tag_LinkStackNode

{

LinkListNode header;

void* item;

} TLinkStackNode;

LinkStack* LinkStack_Create()

{

return LinkList_Create();

}

void LinkStack_Destroy(LinkStack* stack)

{

LinkStack_Clear(stack);

LinkList_Destroy(stack);

}

void LinkStack_Clear(LinkStack* stack)

{

while( LinkStack_Size(stack) > 0 )

{

LinkStack_Pop(stack);

}

}

int LinkStack_Push(LinkStack* stack, void* item)

{

TLinkStackNode* node = (TLinkStackNode*)malloc(sizeof(TLinkStackNode));

int ret = (node != NULL) && (item != NULL);

if( ret )

{

node->item = item;

ret  = LinkList_Insert(stack, (LinkListNode*)node, 0);

}

if( !ret )

{

free(node);

}

return ret;

}

void* LinkStack_Pop(LinkStack* stack)

{

TLinkStackNode* node = (TLinkStackNode*)LinkList_Delete(stack, 0);

void* ret = NULL;

if( node != NULL )

{

ret = node->item;

free(node);

}

return ret;

}

void* LinkStack_Top(LinkStack* stack)

{

TLinkStackNode* node = (TLinkStackNode*)LinkList_Get(stack, 0);

void* ret = NULL;

if( node != NULL )

{

ret = node->item;

}

return ret;

}

int LinkStack_Size(LinkStack* stack)

{

return LinkList_Length(stack);

}

SQueue.h

#ifndef _SQUEUE_H_

#define _SQUEUE_H_

typedef void SQueue;

SQueue* SQueue_Create();

void SQueue_Destroy(SQueue* queue);

void SQueue_Clear(SQueue* queue);

int SQueue_Append(SQueue* queue, void* item);

void* SQueue_Retrieve(SQueue* queue);

void* SQueue_Header(SQueue* queue);

int SQueue_Length(SQueue* queue);

#endif

SQueue.c

#include <stdio.h>

#include <malloc.h>

#include "LinkStack.h"

#include "SQueue.h"

typedef struct _tag_SQueue

{

LinkStack* inStack;

LinkStack* outStack;

} TSQueue;

SQueue* SQueue_Create() // O(1)

{

TSQueue* ret = (TSQueue*)malloc(sizeof(TSQueue));

if( ret != NULL )

{

ret->inStack = LinkStack_Create();

ret->outStack = LinkStack_Create();

if( (ret->inStack == NULL) || (ret->outStack == NULL) )

{

LinkStack_Destroy(ret->inStack);

LinkStack_Destroy(ret->outStack);

free(ret);

ret = NULL;

}

}

return ret;

}

void SQueue_Destroy(SQueue* queue) // O(n)

{

SQueue_Clear(queue);

free(queue);

}

void SQueue_Clear(SQueue* queue) // O(n)

{

TSQueue* sQueue = (TSQueue*)queue;

if( sQueue != NULL )

{

LinkStack_Clear(sQueue->inStack);

LinkStack_Clear(sQueue->outStack);

}

}

int SQueue_Append(SQueue* queue, void* item) // O(1)

{

TSQueue* sQueue = (TSQueue*)queue;

if( sQueue != NULL )

{

LinkStack_Push(sQueue->inStack, item);

}

}

void* SQueue_Retrieve(SQueue* queue) // O(1)

{

TSQueue* sQueue = (TSQueue*)queue;

void* ret = NULL;

if( sQueue != NULL )

{

if( LinkStack_Size(sQueue->outStack) == 0 )

{

while( LinkStack_Size(sQueue->inStack) > 0 )

{

LinkStack_Push(sQueue->outStack, LinkStack_Pop(sQueue->inStack));

}

}

ret = LinkStack_Pop(sQueue->outStack);

}

return ret;

}

void* SQueue_Header(SQueue* queue) // O(1)

{

TSQueue* sQueue = (TSQueue*)queue;

void* ret = NULL;

if( sQueue != NULL )

{

if( LinkStack_Size(sQueue->outStack) == 0 )

{

while( LinkStack_Size(sQueue->inStack) > 0 )

{

LinkStack_Push(sQueue->outStack, LinkStack_Pop(sQueue->inStack));

}

}

ret = LinkStack_Top(sQueue->outStack);

}

return ret;

}

int SQueue_Length(SQueue* queue) // O(1)

{

TSQueue* sQueue = (TSQueue*)queue;

int ret = -1;

if( sQueue != NULL )

{

ret = LinkStack_Size(sQueue->inStack) + LinkStack_Size(sQueue->outStack);

}

return ret;

}

小结:

组合使用两个栈的“后进先出”可以实现队列的“先进先出”

两个栈实现队列的方法复用栈数据结构,实现过程简单而且高效。

两个栈实现的队列操作的时间复杂度能够达到O(1)。

转载于:https://www.cnblogs.com/free-1122/p/11335992.html

数据--第24课 - 队列的特别实现相关推荐

  1. Cris 玩转大数据系列之消息队列神器 Kafka

    Cris 玩转大数据系列之消息队列神器 Kafka Author:Cris 文章目录 Cris 玩转大数据系列之消息队列神器 Kafka Author:Cris 1. Kafka 概述 1.1 消息队 ...

  2. python逐笔输入数据_知到智慧树Python数据分析与数据可视化结课测验

    知到智慧树Python数据分析与数据可视化结课测验答案 更多相关问题 已知三角形三个顶点的坐标是A(-1,2,3),B(1,1,1),C(0,0,5),试证三角形ABC是直角三角形,并求角B-- Wh ...

  3. python 多进程——使用进程池,多进程消费的数据)是一个队列的时候,他会自动去队列里依次取数据...

    我的mac 4核,因此每次执行的时候同时开启4个线程处理: # coding: utf-8import time from multiprocessing import Pooldef long_ti ...

  4. 他用几个公式解释了现金贷业务的风控与运营 (下) 2017-09-18 22:04 风控/运营/违约 “金额如此小的业务,成本极度敏感,刚开始的时候我们在数据成本和坏账成本之间特别纠结。” 以上是许

    他用几个公式解释了现金贷业务的风控与运营 (下) 2017-09-18 22:04风控/运营/违约 "金额如此小的业务,成本极度敏感,刚开始的时候我们在数据成本和坏账成本之间特别纠结.&qu ...

  5. 数据结构之队列的特别实现

    队列的特别实现 上两节讲的队列实现方式确实提高了顺序队列和链式队列的效率,可是实现过程还是比较复杂.这样就有可能导致错误,其实有即能复用之前的代码,又比较高效的队列实现算法的. 那就是用栈来实现,可能 ...

  6. 当且仅当函数依赖a→b在r上成立_数据库第06章关系数据理习题课.ppt

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp数据结构与算法 数据库第06章关系数据理习题课.ppt36页 本 ...

  7. 大数据入门第一课 Hadoop基础知识与电商网站日志数据分析

    大数据入门第一课 Hadoop基础知识与电商网站日志数据分析 本课程从Hadoop核心技术入手,以电商项目为依托,带领你从0基础开始上手,逐步掌握大数据核心技术(如:HDFS.YARN.MapRedu ...

  8. 第24课 Altium Designer20(AD20)+VESC6.4实战教程:长走线、元器件散热与GND铺铜的处理(北冥有鱼)

    第24课 Altium Designer20(AD20)+VESC6.4实战教程:长走线.元器件散热与GND铺铜的处理(北冥有鱼)

  9. 微软认证考试70-461 Modify Data 数据修改 --24%比重--(1)

    附注:微软认证考试70-461范围 Create Database Objects创建数据库对象 (24%) Work with Data数据处理 (27%) Modify Data数据修改 (24% ...

  10. 视频教程-大数据分析师实战课-大数据

    大数据分析师实战课 任老师,Cloudera管理/开发/分析认证讲师,华为高级特聘讲师,新华三大学高级特聘讲师,中国大数据技术与应用联盟高级讲师,全国高校大数据联盟特聘讲师,中国移动高级讲师,前IBM ...

最新文章

  1. HTML5 如何实现拖放'N'拖放
  2. 学生科技周的讲座-2021-内容准备
  3. Android系统分区理解及分区目录细解
  4. Swagger UI
  5. 注解_自定义注解_属性定义
  6. pythoncharm下载cpython失败_pycharm虚拟环境下安装mysqlclient失败
  7. 如何创建MFC模式对话框与非模式对话框
  8. android签名文件查看工具,ionic 发布android,并查看签名文件。
  9. 前端学习(2533):mapgetter和actions
  10. react的导出是怎么实现的_从零开始开发一个 React
  11. 2020过半,程序员“跳槽”还是“卧槽”,你想好了吗?
  12. corosync + pacemaker + drbd 实现mysql存储的高可用(一)
  13. SQL where 条件顺序对性能的影响有哪些
  14. OpenCV中的三种图像数据结构CvMat, IplImage和Mat(二)IplImage
  15. Eclipse闪退解决方案
  16. Windows核心编程_关闭Windows
  17. android 蓝牙编程重点---如何发送和接收16进制数据
  18. 拓端tecdat|R语言离群值处理分析
  19. Snipaste截图软件安装、使用详细教程(附下载链接)
  20. 《算法笔记》Codeup练习 5.1小节 简单数学问题

热门文章

  1. Android反编译与加密(代码混淆)
  2. 周五,放松心情,听我来分享问题背后的背后(一)
  3. java商品类别如何与价格对应_java编写程序实现某超市商品查价功能。从键盘输入商品号,显示对应的商品价格,以“n”结束查询。...
  4. linux导入通达oa数据库,将通达OA迁移到linux平台
  5. c语言知识竞赛题库答案及,《C语言程序设计》复习题库.docx
  6. 奥鹏2019计算机应用基础1,奥鹏东师2019年秋季(计算机应用基础)离线考核(仅供参考).docx...
  7. 一建机电实务教材电子版_一建案例学不透?新版一建机电案例一本通,6大模板案例高清讲解...
  8. 山西计算机职业学校排名2015,2015山西专科学校排名及排行榜
  9. 前端vue的基础使用模板
  10. python3捕获异常_Python 异常处理和捕获信息教程|python3教程|python入门|python教程