数据结构6.通用队列
2016-06-18 09:53
309 查看
引言
数据结构中的队列模型和我们日常生活中的排队情况是一致的,排队买票,窗口一端叫队头,末尾进队叫队尾; 最先在前面买票的先离开,最早进入队列的元素最早离开。 所以队列又称作FIFO表(First in First out)。队列(Queue)是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。
进行插入操作的端称为队尾,进行删除操作的端称为队头。
二、队列定义及实现
队列定义:#ifndef _QUEUE_H_ #define _QUEUE_H_ #include "dlist.h" typedef struct Queue { Dlist *dlist; //封装我们已经实现的链表 }Queue; //1.初始化 Queue *init_queue(void); //2.销毁 void destroy_queue(Queue **queue); //3.入队 void in_queue(Queue *queue, void *value);/*入队返回值:空*/ //4.出队 Boolean out_queue(Queue *queue); //5.得到队首元素 Boolean get_front_queue(Queue *queue, void **value); //6.判断队列是否为空 Boolean is_queue_empty(Queue *queue); //7.得到队列元素个数 int get_queue_count(Queue *queue); #endif
通用链表接口:
#ifndef _DLIST_H_ #define _DLIST_H_ #define TRUE (1) #define FALSE (0) #define ZERO (0) #define ONLY_ONE (1) typedef unsigned char Boolean ; typedef void (*Print_func)(void *value); void print_int(void *data); typedef struct Dlist_node{ struct Dlist_node *prev; struct Dlist_node *next; //指向后一个节点 void *data; }Dlist_node; //通用链表控制信息 typedef struct Dlist{ struct Dlist_node *head; //指向头结点 struct Dlist_node *tail; int count; //这是一个指向某个需要被释放的数据域的函数指针 void (*free)(void *ptr); //比较节点数据域 Boolean (*match)(void *value1, void *value2); //拷贝节点数据域 void *(*copy_node)(void *value); }Dlist; //双端链表的初始化 Dlist *init_dlist(void); //双端链表的销毁 void destroy_dlist(Dlist **dlist);//二重指针 //头部插入 Boolean push_front(Dlist *dlist, void *data); //尾部插入 Boolean push_back(Dlist *dlist, void *data); //头部删除 Boolean pop_front(Dlist *dlist); //尾部删除 Boolean pop_back(Dlist *dlist); //插入到当前节点前 Boolean insert_prev(Dlist *dlist, Dlist_node *node, void *value); //插入到当前节点后 Boolean insert_next(Dlist *dlist, Dlist_node *node, void *value); //删除某个节点 Boolean remove_dlist_node(Dlist *dlist, Dlist_node *node); //显示双端链表信息 void show_dlist(Dlist *dlist, Print_func print); //得到第一个节点数据域 Boolean get_front(Dlist *dlist, void **value); //得到最后一个节点数据域 Boolean get_tail(Dlist *dlist, void **value); //得到链表节点数量 int get_dlist_count(Dlist *dlist); #endif
队列实现:
#include <stdio.h> #include "queue.h" #include "tools.h" //1.初始化 Queue *init_queue(void) { Queue *queue = (Queue *)Malloc(sizeof(Queue)); queue->dlist = init_dlist(); return queue; } //2.销毁 void destroy_queue(Queue **queue) { if(queue == NULL || *queue == NULL) { return; } destroy_dlist( &((*queue)->dlist) ); free(*queue); *queue = NULL; } //3.入队 void in_queue(Queue *queue, void *value)/*入队返回值:空*/ { if(queue == NULL || value == NULL) { return ; } push_back(queue->dlist, value); //后插法 } //4.出队 Boolean out_queue(Queue *queue) { if(queue == NULL || is_queue_empty(queue)) { return FALSE; } return pop_front(queue->dlist); //前删 } //5.得到队首元素 Boolean get_front_queue(Queue *queue, void **value) { if(queue == NULL || is_queue_empty(queue)) { return FALSE; } if(value != NULL){ return get_front(queue->dlist, value); } } //6.判断队列是否为空 Boolean is_queue_empty(Queue *queue) { return get_queue_count(queue) == ZERO; } //7.得到队列元素个数 int get_queue_count(Queue *queue) { if(queue == NULL) { return -1; } return get_dlist_count(queue->dlist); }
由于我们封装的链表操作提供了接口,我们可以发现,再用我们已经实现过的代码去完成新的结构新的操作就会变得简单的多。
由此可见,代码的冗余性低,并实现通用化对学习工作都会有很大的用处。
三、代码功能测试
测试代码:#include <stdio.h> #include "queue.h" int main(int argc, char **argv) { int i = 0; int a[]={1,2,3,4,5}; int *value = NULL; int length = sizeof(a)/sizeof(a[0]); Queue *queue = NULL; queue = init_queue(); for(i=0; i< length;++i) { in_queue(queue, &a[i]); } Dlist_node *node = queue->dlist->head; for(i=0; i< length ;++i) { print_int(node->data); node = node ->next; } printf("\n"); printf("Top:"); get_front_queue(queue, (void **)&value); printf("%d ",*value); printf("\n"); printf("the length:\n"); printf("%d \n",get_queue_count(queue)); for(i = 0; i < length ; ++i) { get_front_queue(queue,(void **)&value); out_queue(queue); printf("%d ",*value); } printf("\n"); destroy_queue(&queue); return 0; }
测试结果:
root@aemonair:# cc.sh *.c Compiling ... -e CC dlist.c main.c queue.c tools.c -g -lpthread -e Completed . -e Sat Jun 18 10:33:45 CST 2016 root@aemonair:# ./dlist 1 2 3 4 5 Top:1 the length: 5 1 2 3 4 5
总结
我们这次还只是很简单的实现了最简单的顺序队列,而且只是仅仅对我们已经实现的链表功能进行再次加工制造,那么,有了这样的通用思想后,我们需要对自己的代码进行模块化,同时不能只是简单的利用这些代码,要从深处底层了解,才能更好的进行使用。对于编程功底的联系以及使用模块化代码并无矛盾,我们一方面要加强代码能力,也要能够利用我们已写过的简单代码,来有更多时间完成更深更有难度的功能。
相关文章推荐
- C#通用邮件发送类分享
- C#数据结构之顺序表(SeqList)实例详解
- C#、ASP.NET通用扩展工具类之TypeParse
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#、ASP.NET通用扩展工具类之LogicSugar
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- C#线程队列用法实例分析
- 算法系列15天速成 第九天 队列
- 数据结构之Treap详解
- C语言单链队列的表示与实现实例详解
- mysql 队列 实现并发读
- C#队列Queue用法实例分析
- C#多线程处理多个队列数据的方法
- C语言循环队列的表示与实现实例详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C++循环队列实现模型
- C#内置队列类Queue用法实例