队列的特别实现

来源:互联网 发布: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
原创粉丝点击