zoukankan      html  css  js  c++  java
  • 数据--第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 ", *(int*)SQueue_Header(queue));

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

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

        {

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

        }  

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

        printf("Length: %d ", 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 ", *(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)。

  • 相关阅读:
    VUE报错: Duplicate keys detected: '0'. This may cause an update error.
    VUE中 resource如何引入和GET POST JSONP 如何使用
    VUE中 axios GET和POST 如何使用
    微信小程序封装组件,子父组件通信 详细解析
    CSS3文字超出块元素显示省略号
    微信小程序处理后端返回图片二进制流,渲染页面
    记录平台向用户发送消息功能界面(HTML+CSS)
    原生JavaScript写出日历功能 无引用Jq
    mongoTemplate Aggregation first
    封装返回前端的通用格式
  • 原文地址:https://www.cnblogs.com/free-1122/p/11335992.html
Copyright © 2011-2022 走看看