如何使用C语言写: Generic Queue
2013-02-27 09:56
387 查看
Model
------------------------------------------------------------------------------------------------------------------------
队列也是限制插入和删除位置的表.
主要操作是enqueue和dequeue操作.
enqueue:入队操作.在表的队尾(rear)插入一个元素.
dequeue:出队操作.删除表的队首(front)元素.
本文使用循环数组实现GenericQueue.需要指定capacity.缺点是超出容量,无法动态增长.当然,可以仿照list的方式克服这个问题.
完整代码详见我的github(https://github.com/gnudennis/ds_c)(genric-queue.h
generic-queue.c generic-queue-test.c)
核心代码
------------------------------------------------------------------------------------------------------------------------
0. Generic Queue定义
1. API
2.Implementation
分析
----------------
本文使用循环数组实现GenericQueue.需要指定capacity.既然是循环数组,就是围成一个圈.也就插入第一个元素没有必要非要放在0处啦.
初始状态:
{
que->size = 0;
que->front = 1;
que->rear = 0;
}
说明这样第一次enqueue操作放在array[1]处,当然:这不是必须的,取决于你想放在那里.
#define mxx
{
que->size = 0;
que->front =m+1;
que->rear = m;
}
就放在array[m+1]处.
------------------------------------------------------------------------------------------------------------------------
队列也是限制插入和删除位置的表.
主要操作是enqueue和dequeue操作.
enqueue:入队操作.在表的队尾(rear)插入一个元素.
dequeue:出队操作.删除表的队首(front)元素.
本文使用循环数组实现GenericQueue.需要指定capacity.缺点是超出容量,无法动态增长.当然,可以仿照list的方式克服这个问题.
完整代码详见我的github(https://github.com/gnudennis/ds_c)(genric-queue.h
generic-queue.c generic-queue-test.c)
核心代码
------------------------------------------------------------------------------------------------------------------------
0. Generic Queue定义
typedef void *ElementAddr; typedef void (*PfCbFree)(ElementAddr); typedef struct QueueRecord { ElementAddr *array; int capacity; int elemsize; int front; int rear; int size; PfCbFree freefn; } *Queue;
1. API
/* Create a new queue */ Queue queue_create(int elemsize, int capacity, PfCbFree freefn); /* Dispose the queue */ void queue_dispose(Queue que); /* Make the give queue empty */ void queue_make_empty(Queue que); /* Return true if the queue is empty */ int queue_is_empty(Queue que); /* Return true if the queue is full */ int queue_is_full(Queue que); /* Insert a new element onto queue */ void queue_enqueue(Queue que, ElementAddr elemaddr); /* Delete the front element off the queue */ void queue_dequeue(Queue que); /* Fetch the front element from the queue */ void queue_front(Queue que, ElementAddr elemaddr); /* Fetch and Delete the front element from the queue */ void queue_front_and_dequeue(Queue que, ElementAddr elemaddr);
2.Implementation
/* Create a new queue with capacity */ Queue queue_create(int elemsize, int capacity, PfCbFree freefn) { Queue que; que = malloc(sizeof(struct QueueRecord)); if ( que == NULL ) { fprintf(stderr, "Out of memory\n"); exit(1); } que->elemsize = elemsize; que->capacity = capacity > MIN_QUEUE_SIZE ? capacity : MIN_QUEUE_SIZE; que->array = malloc(elemsize * que->capacity); if ( que->array == NULL ) { fprintf(stderr, "Out of memory\n"); exit(1); } que->front = 1; que->rear = 0; que->size = 0; que->freefn = freefn; return que; } /* Dispose the queue */ void queue_dispose(Queue que) { if (que != NULL) { queue_make_empty(que); free(que->array); free(que); } } /* Make the give queue empty */ void queue_make_empty(Queue que) { if ( que->freefn ) { int i; for ( i = 0; i < que->size; ++i) { free((char *)que->array + que->elemsize * i); } } que->size = 0; que->front = 1; que->rear = 0; } /* Return true if the queue is empty */ int queue_is_empty(Queue que) { return que->size == 0; } /* Return true if the queue is full */ int queue_is_full(Queue que) { return que->size == que->capacity; } static int successor(Queue que, int index) { if ( ++index == que->capacity) index = 0; return index; } /* Insert a new element onto queue(rear) */ void queue_enqueue(Queue que, ElementAddr elemaddr) { void *target; if ( queue_is_full(que) ) { fprintf(stderr, "Full queue\n"); exit(1); } que->rear = successor(que, que->rear); target = (char *)que->array + que->elemsize * que->rear; memcpy(target, elemaddr, que->elemsize); que->size++; } /* Delete the front element off the queue */ void queue_dequeue(Queue que) { if ( queue_is_empty(que) ) { fprintf(stderr, "Empty queue\n"); exit(1); } if ( que->freefn ) { void *target = (char *)que->array + que->front * que->elemsize; que->freefn(target); } que->size--; que->front = successor(que, que->front); } /* Fetch the front element from the queue */ void queue_front(Queue que, ElementAddr elemaddr) { void *target = (char *)que->array + que->front * que->elemsize; memcpy(elemaddr, target, que->elemsize); } /* Fetch and Delete the front element from the queue */ void queue_front_and_dequeue(Queue que, ElementAddr elemaddr) { void *target; if ( queue_is_empty(que) ) { fprintf(stderr, "Empty queue\n"); exit(1); } target = (char *)que->array + que->front * que->elemsize; memcpy(elemaddr, target, que->elemsize); que->size--; que->front = successor(que, que->front); }
分析
----------------
本文使用循环数组实现GenericQueue.需要指定capacity.既然是循环数组,就是围成一个圈.也就插入第一个元素没有必要非要放在0处啦.
初始状态:
{
que->size = 0;
que->front = 1;
que->rear = 0;
}
说明这样第一次enqueue操作放在array[1]处,当然:这不是必须的,取决于你想放在那里.
#define mxx
{
que->size = 0;
que->front =m+1;
que->rear = m;
}
就放在array[m+1]处.
相关文章推荐
- 如何使用C语言实现递归调用
- C语言中如何使用宏
- 如何使用C语言搜索指定目录下的所有文件?
- C语言中如何使用宏[转]
- 在linux下,如何在C语言中使用正则表达式
- C语言中如何使用宏
- 如何用C语言封装 C++的类,在 C里面使用
- C语言的函数中,如何使用指针交换两个数的值,深入理解指针
- 如何优雅地使用c语言编写爬虫
- 如何在C语言中使用constructor和destructor,gcc环境
- C语言qsort函数如何使用
- C语言 如何在函数中使用指针?
- C语言中如何使用宏 包括单双井号 可变参数
- 使用VS2012编写C语言带图走心攻略(如何使用vs2012编程)
- Linux系统,使用C语言如何产生UUID
- 如何使用C语言实现打地鼠的游戏
- 如何使用 Forms 身份验证创建 GenericPrincipal 对象
- C语言中如何使用宏
- 如何使用c语言解析httppost请求
- 【C++ STL应用与实现】13: 如何使用std::queue和std::priority_queue