队列的特别实现
来源:互联网 发布:iphone酷狗网络异常 编辑:程序博客网 时间:2024/03/29 17:12
可以用栈实现队列
采用前文中的改进方式会让队列的实现变得复杂,现在采用栈的方式来实现队列。
如下图所示:
实现思路:
1、准备两个栈用于实现队列:inStack和outStack
2、当有新元素入队时:将其压入inStack中
3、当需要出队时:
当outStack为空时:
- 将inStack中的元素逐一弹出并压入outStack中
- 将outStack的栈顶元素弹出
当outStack不为空时:
- 直接将outStack的栈顶元素弹出
代码实现
特别队列实现方式要用到栈的结构,因此需要使用到链表和链式栈的相关代码:
//特殊队列 头文件 SpecialQueue.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
//特殊队列 源文件 SpecialQueue.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){ TSQueue* sQueue = (TSQueue*)queue; SQueue_Clear(queue); LinkStack_Destroy(sQueue->inStack); LinkStack_Destroy(sQueue->outStack); 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) 出队列 //最坏情况下O(n),需要看平均情况,每个元素都要压入in出in压入out出out,平均情况为O(1) { TSQueue* sQueue = (TSQueue*)queue; void* ret = NULL; if( sQueue != NULL ) { if( LinkStack_Size(sQueue->outStack) == 0 ) { while( LinkStack_Size(sQueue->inStack) > 0 )//in栈的数据压入out栈 { LinkStack_Push(sQueue->outStack, LinkStack_Pop(sQueue->inStack)); } } ret = LinkStack_Pop(sQueue->outStack);//out栈的数据出栈 } 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)。
0 0
- 队列的特别实现
- 【十四】队列的特别实现--利用双栈
- SpringMVC特别的实现类
- 用js实现特别好看的table
- 特别简单的android瀑布流实现
- 队列的实现:顺序队列
- 队列的实现:链式队列
- 队列----循环队列的实现
- 特别特别繁忙的九月
- hdu 1874 dijkstra 队列实现 比数组高效特别在稀疏图
- 队列实现 队列的链式结构实现
- 利用js实现选项卡的特别效果
- 堆栈,队列的实现
- 链队列的实现
- 队列的实现
- 队列的实现
- java 实现的队列
- 工作队列的实现
- idea快捷键
- HTML元素及属性(二)
- HDU 1005 Number Sequence(循环节) *
- WCF通过配置文件搭建—— 一起嗨
- 两个相似类属性快速复制
- 队列的特别实现
- 图像矩阵——灰度与彩色图
- leetcode-501-Find Mode in Binary Search Tree
- 关于mac系统外接键盘的设置
- 2017.02.15总结
- ContentProvider的工作过程
- 让你的DBCP连接池连接不超时
- PAT-A 1009. Product of Polynomials (25)
- 串口2