zoukankan      html  css  js  c++  java
  • 5.队列

    一.Queue 基本概念

    队列是一种特殊的线性表

    队列仅在线性表的两端进行操作

    队头(Front):取出数据元素的一端

    队尾(Rear):插入数据元素的一端

    队列不允许在中间部位进行操作!

    常用操作

    • 销毁队列
    • 清空队列
    • 进队列
    • 出队列
    • 获取队头元素
    • 获取队列的长度

    二.队列的顺序存储设计与实现

    seqlist.h

    #ifndef __MY_SEQLIST_H__
    #define __MY_SEQLIST_H__
    
    #define DLL_API  __declspec(dllexport)    //_declspec(dllexport):导出标志
    
    typedef void SeqList;
    typedef void SeqListNode;
    
    
    // 创建线性表
    DLL_API SeqList* SeqList_Create(int capacity);
    
    // 销毁线性表
    DLL_API void SeqList_Destroy(SeqList *list);
    
    // 清空线性表
    DLL_API void SeqList_Clear(SeqList *list);
    
    // 获得线性表的长度
    DLL_API int SeqList_Length(SeqList *list);
    
    // 获得线性表的容量
    DLL_API int SeqList_Capacity(SeqList *list);
    
    // 向线性表中插入一个元素
    DLL_API int SeqList_Insert(SeqList *list, SeqListNode *node, int pos);
    
    // 获取线性表中某一个位置的元素
    DLL_API SeqListNode* SeqList_Get(SeqList *list, int pos);
    
    // 删除线性表中某一个位置的元素
    DLL_API SeqListNode* SeqList_Delete(SeqList *list, int pos);
    
    
    
    #endif

    seqlist.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "seqlist.h"
    
    
    typedef struct _tag_SeqList
    {
        int capacity;
        int length;
        unsigned int *node; // unsigned int array[capacity]
    }TSeqList;
    
    
    
    // 创建线性表
    SeqList* SeqList_Create(int capacity)
    {
        TSeqList *ret = NULL;
        if (capacity < 0)
        {
            return NULL;
        }
        ret = malloc(sizeof(TSeqList) + sizeof(unsigned int)*capacity);
        if (ret == NULL)
        {
            return NULL;
        }
        memset(ret, 0, sizeof(TSeqList)+sizeof(unsigned int)*capacity);
        ret->node = (unsigned int *)(ret + 1); // ret 向后跳转sizeof(TSeqList)
        ret->capacity = capacity;
        ret->length = 0;
    
        return ret;
    }
    
    
    // 销毁线性表
    void SeqList_Destroy(SeqList *list)
    {
        if (list != NULL)
        {
            free(list);
        }
    
    }
    
    
    // 清空线性表
    void SeqList_Clear(SeqList *list)
    {
        TSeqList *tList = NULL;
        if (list == NULL)
        {
            return;
        }
        tList = (SeqList*)list;
        tList->length = 0;
    }
    
    
    // 获得线性表的长度
    int SeqList_Length(SeqList *list)
    {
        TSeqList *tList = NULL;
        tList = (TSeqList*)list;
        if (tList == NULL)
        {
            return -1;
        }
        return tList->length;
    }
    
    
    
    // 获得线性表的容量
    int SeqList_Capacity(SeqList *list)
    {
        TSeqList *tList = NULL;
        tList = (TSeqList*)list;
        if (tList == NULL)
        {
            return -1;
        }
        return tList->capacity;
    }
    
    // 向线性表中插入一个元素
    DLL_API int SeqList_Insert(SeqList *list, SeqListNode *node, int pos)
    {
        int i = 0;
        TSeqList *tList = NULL;
        tList = (TSeqList*)list;
    
        // 保证传入的线性表和元素节点不能为NULL
        if (list == NULL || node == NULL)
        {
            return -1;
        }
    
        // 判断该线性表是否已满
        if (tList->length >= tList->capacity)
        {
            return -2;
        }
    
        // 判断插入索引是否合法
        if (pos < 0 || pos >= tList->capacity)
        {
            return -3;
        }
    
        // 若索引值大于线性表当前长度,则将元素插入到线性表的末尾
        if (pos >= tList->length)
        {
            pos = tList->length;
        }
    
        // 插入算法
        // 将pos位置后的元素移次向后移
        for (i = tList->length; i > pos; i--)
        {
            // 更新后移元素的值
            tList->node[i] = tList->node[i - 1];
        }
    
        // 元素后移完毕后,将元素放到指定的位置
        tList->node[pos] = (unsigned int)node;
        tList->length ++;
        return 0;
    }
    
    
    
    // 获取线性表中某一个位置的元素
    SeqListNode* SeqList_Get(SeqList *list, int pos)
    {
        SeqListNode *ret = NULL;
        TSeqList *tList = NULL;
        tList = (TSeqList*)list;
        
        // 过滤非法参数
        if (list == NULL || pos < 0 || pos >= tList->length)
        {
            return NULL;
        }
    
        ret = (SeqListNode*)tList->node[pos];
        return ret;
    }
    
    
    // 删除线性表中某一个位置的元素
    SeqListNode* SeqList_Delete(SeqList *list, int pos)
    {
        int i = 0;
        TSeqList *tList = NULL;
        SeqListNode *ret = NULL;
        tList = (TSeqList*)list;
    
        if (list == NULL || pos < 0 || pos >= tList->length)
        {
            return NULL;
        }
    
        ret = (SeqListNode*)tList->node[pos];
        // 删除算法
        for (i=pos+1; i<tList->length; i++)
        {
            tList->node[i - 1] = tList->node[i];
        }
        tList->length--;
    
        return ret;
    }

    seqqueue.h

    #ifndef __MY_SEQ_QUEUE_H__
    #define __MY_SEQ_QUEUE_H__
    
    
    
    typedef void SeqQueue;
    
    // 创建队列
    SeqQueue* SeqQueue_Create(int capacity);
    
    // 销毁队列
    void SeqQueue_Destroy(SeqQueue* queue);
    
    // 清空队列
    void SeqQueue_Clear(SeqQueue* queue);
    
    // 向队尾添加元素
    int SeqQueue_Append(SeqQueue* queue, void* item);
    
    // 移除队列头部元素
    void* SeqQueue_Retrieve(SeqQueue* queue);
    
    // 获取队列头部元素
    void* SeqQueue_Header(SeqQueue* header);
    
    // 获取队列长度
    int SeqQueue_Length(SeqQueue* length);
    
    // 获取队列容量
    int SeqQueue_Capacity(SeqQueue* queue);
    
    
    
    #endif

    seqqueue.c

    #include "seqqueue.h"
    #include "seqlist.h"
    
    
    // 创建队列
    SeqQueue* SeqQueue_Create(int capacity)
    {
        return SeqList_Create(capacity);
    }
    
    // 销毁队列
    void SeqQueue_Destroy(SeqQueue* queue)
    {
        SeqList_Destroy(queue);
    }
    
    // 清空队列
    void SeqQueue_Clear(SeqQueue* queue)
    {
        SeqList_Clear(queue);
    }
    
    // 向队尾添加元素,相当于向线性表的尾部插入元素
    int SeqQueue_Append(SeqQueue* queue, void* item)
    {
        return SeqList_Insert(queue, item, SeqList_Length(queue));
    }
    
    
    // 移除队列头部元素
    void* SeqQueue_Retrieve(SeqQueue* queue)
    {
        return SeqList_Delete(queue, 0);
    }
    
    
    // 获取队列头部元素
    void* SeqQueue_Header(SeqQueue* queue)
    {
        return SeqList_Get(queue, 0);
    }
    
    // 获取队列长度
    int SeqQueue_Length(SeqQueue* queue)
    {
        return SeqList_Length(queue);
    }
    
    // 获取队列容量
    int SeqQueue_Capacity(SeqQueue* queue)
    {
        return SeqList_Capacity(queue);
    }

    运行结果:

    current queue capacity is: 10

    current queue length is: 6

    current student age is: 12
    current new length is: 0
    请按任意键继续. . .

    三.队列的链式存储设计与实现

    linklist.h

    #ifndef __MY_LINKLIST_H__
    #define __MY_LINKLIST_H__
    
    #define DLL_API  __declspec(dllexport)    //_declspec(dllexport):导出标志
    
    typedef void LinkList;
    
    typedef struct _tag_LinkListNode
    {
        struct _tag_LinkListNode* next;      // 当前节点需要指向下一个节点的地址
    }LinkListNode;
    
    
    
    
    DLL_API LinkList* LinkList_Create();
    
    DLL_API void LinkList_Destroy(LinkList *list);
    
    DLL_API void LinkList_Clear(LinkList *list);
    
    DLL_API int LinkList_Length(LinkList *list);
    
    DLL_API int LinkList_Insert(LinkList *list, LinkListNode *node, int pos);
    
    DLL_API LinkListNode* LinkList_Get(LinkList *list, int pos);
    
    DLL_API LinkListNode* ListList_Delete(LinkList *list, int pos);
    
    
    #endif

    linklist.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "linklist.h"
    
    
    typedef struct _tag_LinkList
    {
        LinkListNode header;              //  链表中需要包含一个头节点
        int length;
    }TLinkList;
    
    
    // 创建链表
    LinkList* LinkList_Create()
    {
        TLinkList *ret = (TLinkList*)malloc(sizeof(TLinkList));
        if (ret == NULL) return NULL;
        memset(ret, 0, sizeof(TLinkList));
    
        ret->header.next = NULL;
        ret->length = 0;
        return ret;
    }
    
    
    // 销毁链表
    void LinkList_Destroy(LinkList *list)
    {
        if (list != NULL)
        {
            free(list);
        }
    }
    
    
    // 清空链表
    void LinkList_Clear(LinkList *list)
    {
        TLinkList *tList = NULL;
        if (list == NULL) return;
        
        tList = (TLinkList*)list;
        tList->header.next = NULL;
        tList->length = 0;
    }
    
    
    // 获取当前链表长度
    int LinkList_Length(LinkList *list)
    {
        TLinkList *tList = NULL;
        if (list == NULL) return -1;
        tList = (TLinkList*)list;
    
        return tList->length;
    }
    
    
    // 向当前链表插入数据
    int LinkList_Insert(LinkList *list, LinkListNode *node, int pos)
    {
        TLinkList *tList = NULL;
        LinkListNode *current = NULL;
        int i = 0;
    
        tList = (TLinkList*)list;
    
        // 过滤非法参数
        if (list == NULL || pos < 0)
        {
            return -1;
        }
    
        /* 
         * 插入要点
         *1.让新插入的元素节点指向原有位置的元素节点
         *2.修改原有位置的前一个元素节点的指向(更新指向为新插入的元素节点)
         */
    
        // 准备环境让辅助指针变量 指向链表头节点
        current = &tList->header;
        // 将当前链表的节点移动到待插入节点的前一个节点的位置(假如待插入的位置是3,则移动到2号位置)
        for (i = 0; i < pos && (current->next != NULL); i++)
        {
            current = current->next; // 将辅助节点运动到指定位置(待插入位置的前一个节点)
        }
        // 让新插入的元素节点指向原有位置的元素节点
        node->next = current->next;
        current->next = node;
        tList->length++;
    
        return 0;
    }
    
    LinkListNode* LinkList_Get(LinkList *list, int pos)
    {
        TLinkList *tList = NULL;
        int i = 0;
        LinkListNode *current = NULL;
        LinkListNode *ret = NULL;
    
    
        tList = (TLinkList *)list;
        // 过滤非法参数
        if (list == NULL || pos < 0 || pos >= tList->length)
        {
            return NULL;
        }
    
        
        current = &tList->header;
        // 将辅助指针变量运行到待获取元素的前一个节点
        for (i = 0; i < pos && (current->next != NULL); i++)
        {
            current = current->next;
        }
    
        ret = current->next;
        return ret;
    }
    
    
    
    LinkListNode* ListList_Delete(LinkList *list, int pos)
    {
    
        TLinkList *tList = NULL;
        tList = (TLinkList *)list;
        LinkListNode *current = NULL;
        LinkListNode *ret = NULL;
        int i = 0;
    
        // 过滤非法参数
        if (list == NULL || pos < 0 || pos >= tList->length)
        {
            return NULL;
        }
    
        // 移动辅助指针变量
        current = &tList->header;
        for (i = 0; i < pos && (current->next != NULL); i++)
        {
            current = current->next;
        }
        ret = current->next;
        
        // 将待删除位置的前一个节点的指向连接到删除位置节点的指向
        current->next = ret->next;
        // 将链表长度-1
        tList->length--;
    
        return ret;
    }

    linkqueue.h

    #ifndef __MY_LINK_QUEUE_H__
    #define __MY_LINK_QUEUE_H__
    
    
    
    typedef void LinkQueue;
    
    // 创建队列
    LinkQueue* LinkQueue_Create();
    
    // 销毁队列
    void LinkQueue_Destroy(LinkQueue* queue);
    
    // 清空队列
    void LinkQueue_Clear(LinkQueue* queue);
    
    // 向队尾添加元素
    int LinkQueue_Append(LinkQueue* queue, void* item);
    
    // 删除队首元素
    void* LinkQueue_Retrieve(LinkQueue* queue);
    
    // 获取队首元素
    void* LinkQueue_Header(LinkQueue* header);
    
    // 获取当前队列长度
    int LinkQueue_Length(LinkQueue* queue);
    
    
    
    #endif

    linkqueue.c

    #include <stdlib.h>
    #include <string.h>
    
    #include "linkqueue.h"
    #include "linklist.h"
    
    
    typedef struct _tag_LinkQueueNode
    {
        LinkListNode node;
        void *item;
    }TLinkQueueNode;
    
    
    
    // 创建队列
    LinkQueue* LinkQueue_Create()
    {
        return LinkList_Create();
    }
    
    // 销毁队列
    void LinkQueue_Destroy(LinkQueue* queue)
    {
        LinkQueue_Clear(queue);
        LinkList_Destroy(queue);
    }
    
    // 清空队列
    void LinkQueue_Clear(LinkQueue* queue)
    {
        while (LinkQueue_Length(queue) > 0)
        {
            LinkQueue_Retrieve(queue);     // 该函数包含内存释放函数
        }
    }
    
    // 向队列中添加元素,相当于向队列的队尾添加元素
    int LinkQueue_Append(LinkQueue* queue, void* item)
    {
        int ret = 0;
        TLinkQueueNode *node = NULL;
        node = (TLinkQueueNode*)malloc(sizeof(TLinkQueueNode));
        if (node == NULL) return -1;
        memset(node, 0, sizeof(TLinkQueueNode));
        node->item = item;
    
        ret = LinkList_Insert(queue, (LinkListNode *)node, LinkList_Length(queue));
        if (ret != 0) // 插入失败
        {
            free(node);
            return ret;
        }
        return ret;
    }
    
    // 删除队首元素
    void* LinkQueue_Retrieve(LinkQueue* queue)
    {
        void *ret = NULL;
        TLinkQueueNode *node = NULL;
        node = (TLinkQueueNode*)ListList_Delete(queue, 0);
        if (node == NULL) return NULL;
    
        ret = node->item;
        free(node);
        node = NULL;
        return ret;
    }
    
    // 获取队首元素
    void* LinkQueue_Header(LinkQueue* queue)
    {
        void *ret = NULL;
        TLinkQueueNode *node = NULL;
        node = (TLinkQueueNode*)LinkList_Get(queue, 0);
        if (node == NULL) return NULL;
    
        ret = node->item;
        return ret;
    }
    
    // 获取当前队列长度
    int LinkQueue_Length(LinkQueue* queue)
    {
        return LinkList_Length(queue);
    }

    test.c

    #include <stdio.h>
    #include <stdlib.h>
    
    #include "linkqueue.h"
    
    
    typedef struct _Student
    {
        char name[20];
        int age;
    }Student;
    
    
    
    int main()
    {
        Student s1, s2, s3, s4, s5, s6;
        s1.age = 11;
        s2.age = 12;
        s3.age = 13;
        s4.age = 14;
        s5.age = 15;
        s6.age = 16;
    
    
        LinkQueue *queue = LinkQueue_Create();
        if (queue != NULL)
        {
            LinkQueue_Append(queue, &s1);
            LinkQueue_Append(queue, &s2);
            LinkQueue_Append(queue, &s3);
            LinkQueue_Append(queue, &s4);
            LinkQueue_Append(queue, &s5);
            LinkQueue_Append(queue, &s6);
            
            printf("current queue length is: %d
    ",LinkQueue_Length(queue));
            printf("
    ");
            
            // 移除队首元素
            LinkQueue_Retrieve(queue);
            Student *pStu = LinkQueue_Header(queue);
            printf("current header age is %d
    ", pStu->age);
            printf("
    ");
            
            // 清空队列
            LinkQueue_Clear(queue);
            int new_length = LinkQueue_Length(queue);
            printf("currnet queue new length is: %d
    ",new_length);
    
        }
    
        system("pause");
        return 0;
    }

    运行结果:

    current queue length is: 6

    current header age is 12

    currnet queue new length is: 0
    请按任意键继续. . .

  • 相关阅读:
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:在函数‘_start’中: (.text+0x20):对‘main’未定义的引用
    W: 仓库 “http://ppa.launchpad.net/levi-armstrong/qt-libraries-trusty/ubuntu xenial Release” 没有 Release 文件。
    sudo apt-get常用命令
    Windows 下 MQTT 服务器搭建之Apollo
    sudo apt-get update报错E: 部分索引文件下载失败。如果忽略它们,那将转而使用旧的索引文件。
    struct.error: cannot convert argument to integer解决办法
    PHP MySQL 创建数据库和表 之 Create
    PHP MySQL 连接数据库 之 Connect
    飞行的架构师和奔跑的程序员
    hdu 5610 Baby Ming and Weight lifting
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/7266983.html
Copyright © 2011-2022 走看看