数据--第24课 - 队列的特别实现
第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课 - 队列的特别实现相关推荐
- Cris 玩转大数据系列之消息队列神器 Kafka
Cris 玩转大数据系列之消息队列神器 Kafka Author:Cris 文章目录 Cris 玩转大数据系列之消息队列神器 Kafka Author:Cris 1. Kafka 概述 1.1 消息队 ...
- python逐笔输入数据_知到智慧树Python数据分析与数据可视化结课测验
知到智慧树Python数据分析与数据可视化结课测验答案 更多相关问题 已知三角形三个顶点的坐标是A(-1,2,3),B(1,1,1),C(0,0,5),试证三角形ABC是直角三角形,并求角B-- Wh ...
- python 多进程——使用进程池,多进程消费的数据)是一个队列的时候,他会自动去队列里依次取数据...
我的mac 4核,因此每次执行的时候同时开启4个线程处理: # coding: utf-8import time from multiprocessing import Pooldef long_ti ...
- 他用几个公式解释了现金贷业务的风控与运营 (下) 2017-09-18 22:04 风控/运营/违约 “金额如此小的业务,成本极度敏感,刚开始的时候我们在数据成本和坏账成本之间特别纠结。” 以上是许
他用几个公式解释了现金贷业务的风控与运营 (下) 2017-09-18 22:04风控/运营/违约 "金额如此小的业务,成本极度敏感,刚开始的时候我们在数据成本和坏账成本之间特别纠结.&qu ...
- 数据结构之队列的特别实现
队列的特别实现 上两节讲的队列实现方式确实提高了顺序队列和链式队列的效率,可是实现过程还是比较复杂.这样就有可能导致错误,其实有即能复用之前的代码,又比较高效的队列实现算法的. 那就是用栈来实现,可能 ...
- 当且仅当函数依赖a→b在r上成立_数据库第06章关系数据理习题课.ppt
您所在位置:网站首页 > 海量文档  > 计算机 > 数据结构与算法 数据库第06章关系数据理习题课.ppt36页 本 ...
- 大数据入门第一课 Hadoop基础知识与电商网站日志数据分析
大数据入门第一课 Hadoop基础知识与电商网站日志数据分析 本课程从Hadoop核心技术入手,以电商项目为依托,带领你从0基础开始上手,逐步掌握大数据核心技术(如:HDFS.YARN.MapRedu ...
- 第24课 Altium Designer20(AD20)+VESC6.4实战教程:长走线、元器件散热与GND铺铜的处理(北冥有鱼)
第24课 Altium Designer20(AD20)+VESC6.4实战教程:长走线.元器件散热与GND铺铜的处理(北冥有鱼)
- 微软认证考试70-461 Modify Data 数据修改 --24%比重--(1)
附注:微软认证考试70-461范围 Create Database Objects创建数据库对象 (24%) Work with Data数据处理 (27%) Modify Data数据修改 (24% ...
- 视频教程-大数据分析师实战课-大数据
大数据分析师实战课 任老师,Cloudera管理/开发/分析认证讲师,华为高级特聘讲师,新华三大学高级特聘讲师,中国大数据技术与应用联盟高级讲师,全国高校大数据联盟特聘讲师,中国移动高级讲师,前IBM ...
最新文章
- HTML5 如何实现拖放'N'拖放
- 学生科技周的讲座-2021-内容准备
- Android系统分区理解及分区目录细解
- Swagger UI
- 注解_自定义注解_属性定义
- pythoncharm下载cpython失败_pycharm虚拟环境下安装mysqlclient失败
- 如何创建MFC模式对话框与非模式对话框
- android签名文件查看工具,ionic 发布android,并查看签名文件。
- 前端学习(2533):mapgetter和actions
- react的导出是怎么实现的_从零开始开发一个 React
- 2020过半,程序员“跳槽”还是“卧槽”,你想好了吗?
- corosync + pacemaker + drbd 实现mysql存储的高可用(一)
- SQL where 条件顺序对性能的影响有哪些
- OpenCV中的三种图像数据结构CvMat, IplImage和Mat(二)IplImage
- Eclipse闪退解决方案
- Windows核心编程_关闭Windows
- android 蓝牙编程重点---如何发送和接收16进制数据
- 拓端tecdat|R语言离群值处理分析
- Snipaste截图软件安装、使用详细教程(附下载链接)
- 《算法笔记》Codeup练习 5.1小节 简单数学问题
热门文章
- Android反编译与加密(代码混淆)
- 周五,放松心情,听我来分享问题背后的背后(一)
- java商品类别如何与价格对应_java编写程序实现某超市商品查价功能。从键盘输入商品号,显示对应的商品价格,以“n”结束查询。...
- linux导入通达oa数据库,将通达OA迁移到linux平台
- c语言知识竞赛题库答案及,《C语言程序设计》复习题库.docx
- 奥鹏2019计算机应用基础1,奥鹏东师2019年秋季(计算机应用基础)离线考核(仅供参考).docx...
- 一建机电实务教材电子版_一建案例学不透?新版一建机电案例一本通,6大模板案例高清讲解...
- 山西计算机职业学校排名2015,2015山西专科学校排名及排行榜
- 前端vue的基础使用模板
- python3捕获异常_Python 异常处理和捕获信息教程|python3教程|python入门|python教程