数据结构队列之环形队列的动态数组实现:queue
来源:互联网 发布:搞笑自拍软件 编辑:程序博客网 时间:2024/05/21 21:35
queue: 也是一种线性的数据结构,其操作一般来讲也是受限的,典型特征是(First in, First out, FIFO)先进先出;
进入队列的元素总是在队列的tail入队,离开队列的元素总是从队列的head离开。
其实实现有多种方式:
1. 用链表实现,head指针指向queue的head, tail指针指向queue的tail;
使用的内存空间就是队列中所有元素节点的空间,但是此实现无法随机访问队列中的元素(这是链表本质决定的)。
使用链表的实现会当元素频繁入队的话,会频繁的分配内存空间; 当元素入队时也要频繁地释放元素的内存空间。
2. 用数组实现:
a. 静态数组的实现:有限容量的队列,一般情况下通过实现环形queue以实现数组空间的充分利用。此实现,使用于具体需求确定的情形。
b. 动态数组的实现:动态数组实现的环形queue,除了具有静态数组实现的环形queue的优点外,还能根据需求的变化,自动的调整队列的内存。(可谓有点智能)。
环形队列的实现要点:可谓是队列为空的标记,
为了简便起见,本文的实现通过将tail永远指向queue的最后一个元素的下一个元素空间位置,即所谓的留出最后一个的元素空间作为标记;
1. 初始化 queue.head == queue.tail 为空; (tail始终指向队列中最后一个元素的下一个位置);
2. enqueue: 元素入队,(因为tail指向的一个节点的元素空间总是预留的), 是否需要环形调整,queue是否已满(++tail == head),队满增加存储空间,调整队列;
3. dequeue: 队列不为空,将对头元素出对,是否需要环形调整,预留空间是否过多,如果是做相应的调整。
4.队列的销毁;
注意,队列空,队列满的标志。
用动态数组实现的环形队列的代码如下:
1. queue的接口规范文件:queue.h
#ifndef QUEUE_H#define QUEUE_H#include <stdio.h>#include <stdlib.h>#include <string.h>/* initial queue capacity in terms of elements */#defineQUEUE_INITIAL_SIZE1 //1024; 1 just used to test in case;#define CHECK_MEM(p) \if ((p) == NULL) { \ fprintf(stderr, "out of memory: in file %s, line %d, function %s.\n", __FILE__, __LINE__, __FUCTION__); \ exit(1); \}typedef struct queue_t { void *base; void *head; /* head points to oldest element */ void *tail; /* tail points to the next element position to the earliest element */ int element_size; /* element size */ int capacity; /* capacity */} queue;/* queue operations */void queue_init(queue *queue, int element_size);void queue_free(queue *queue);int queue_empty(queue *queue);void enqueue(queue *queue, void *element);void * dequeue(queue *queue);int queue_size(queue *queue);void queue_clear(queue *queue);#endif /* QUEUE_H */
#include "queue.h"/* queue operations */void queue_init(queue *queue, int element_size) { queue->base = (void *) malloc(QUEUE_INITIAL_SIZE * element_size); if (queue->base == NULL) { fprintf(stderr, "out of memory (in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } queue->head = queue->base; queue->tail = queue->base; queue->element_size = element_size; queue->capacity = QUEUE_INITIAL_SIZE * element_size;}void queue_free(queue *queue) { if (queue->base != NULL) { free(queue->base); queue->base = NULL; } queue->head = NULL; queue->tail = NULL; queue->element_size = 0; queue->capacity = 0;}int queue_empty(queue *queue) { return (queue->head == queue->tail) ? 1 : 0;}void enqueue(queue *queue, void *element) { void *newbase; int n; memcpy(queue->tail, element, queue->element_size); queue->tail += queue->element_size; if (queue->tail == (queue->base + queue->capacity)) { queue->tail = queue->base; } /* queue not full, done */ if (queue->tail != queue->head) return; /* queue is full, allocate more memory and move data */ newbase = (void *) malloc(queue->capacity << 1); if (newbase == NULL) { fprintf(stderr, "out of memory (in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__); queue_free(queue); exit(1); } n = queue->base + queue->capacity - queue->head; memcpy(newbase, queue->head, n); if(queue->tail > queue->base) { memcpy(newbase + n, queue->base, queue->tail - queue->base); } free(queue->base); queue->base = newbase; queue->head = queue->base; queue->tail = queue->base + queue->capacity; queue->capacity <<= 1;}void * dequeue(queue *queue) { void *p; void *newbase; if(queue_empty(queue))return NULL; int byte_size = queue_size(queue) * queue->element_size; int n; if(byte_size > QUEUE_INITIAL_SIZE && byte_size < (queue->capacity >> 1) ) { if(queue->head <= queue->tail) { n = queue->tail - queue->head; newbase = (void *) malloc(n); if (newbase == NULL) { fprintf(stderr, "memory error: (in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__); queue_free(queue); exit(1); } memcpy(newbase, queue->head, n); } else { n = queue->tail + queue->capacity - queue->head; newbase = (void *) malloc(queue->capacity >> 1); if (newbase == NULL) { fprintf(stderr, "memory error: (in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__); queue_free(queue); exit(1); } int right = queue->base + queue->capacity - queue->head; memcpy(newbase, queue->head, right); memcpy(newbase + right, queue->base, queue->tail - queue->base); } free(queue->base); queue->base = newbase; queue->head = newbase; queue->tail = newbase + n; queue->capacity >>= 1; } p = queue->head; queue->head += queue->element_size; if(queue->head == (queue->base + queue->capacity)) { queue->head = queue->base; } return p;}int queue_size(queue *queue) { if(queue->head <= queue->tail) { return (queue->tail - queue->head) / queue->element_size; }else { return (queue->tail + queue->capacity - queue->head) / queue->element_size; }}/* just clear elements to queue empty, but don't free memory */void queue_clear(queue *queue) { queue->head = queue->base; queue->tail = queue->base;}
3. 对queue的测试代码:main.c
#include "queue.h"void printArray(int a[], int len);int main(int argc, char* argv[]) { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int len = sizeof(a)/sizeof(a[0]); int i; queue queue; printArray(a, len); queue_init(&queue, sizeof(a[0]));// printf("queue capacity:%d\n", queue.capacity);// printf("queue size: %d\n", queue_size(&queue)); for(i = 0; i < len; ++i) { enqueue(&queue, &a[i]);// printf("queue capacity:%d\n", queue.capacity);// printf("queue size: %d\n", queue_size(&queue)); }// printf("queue capacity:%d\n", queue.capacity);// printf("queue size: %d\n", queue_size(&queue)); while(!queue_empty(&queue)) { printf("%d\t", *(int*)dequeue(&queue));// printf("queue capacity:%d\n", queue.capacity);// printf("queue size: %d\n", queue_size(&queue)); } printf("\n");// printf("queue capacity:%d\n", queue.capacity);// printf("queue size: %d\n", queue_size(&queue)); queue_free(&queue); return 0;}void printArray(int a[], int len) { int i; for(i=0; i<len; i++) { printf("%d\t", a[i]); } printf("\n");}
用例测试结果:
- 数据结构队列之环形队列的动态数组实现:queue
- 环形队列的数组实现
- 数组实现的 环形队列
- 算法-一种数组环形队列的数据结构
- c语言数据结构实现-数组队列/环形队列
- 数据结构之环形队列实现(1)
- 无锁队列的环形数组实现(Lock Free Queue Implementation in Ring Array)
- 数据结构之队列queue
- 环形队列的实现
- 经典数据结构之数组实现的队列
- 数据结构学习之队列的数组实现
- 数据结构之数组实现队列
- java之环形队列的实现
- C++之环形队列的实现
- 【数据结构】队列-数组的实现
- Java 数据结构之 Queue(队列)
- 数据结构学习:环形队列的模板类实现
- 数据结构之队列(数组队列)
- 加载不同格式类型图片封转函数(流中加载)
- Android ApiDemos示例解析(175):Views->Lists->8. Photos
- (四) MvcContrib插件实现MVC的分页
- 关于osip协议栈的优化
- 服务器推送数据 和 客户端定时访问服务器的实现
- 数据结构队列之环形队列的动态数组实现:queue
- 黑马程序员之VS2010学习笔记:VS2010MSDN安装图解
- TCP协议三次握手过程分析
- vs断点调试需要修改的几个选项
- Segue特殊用法:UITableViewController根据参数导航到不同的子页面或自身
- LocalActivityManager没有从内部mActivities 地图上删除activity成功
- 数据库命名规范
- psftp 便捷使用
- Apache/Nginx+MySql+PHP配置