[转]基于Cmockery和TDD开发循环Queue结构和基本操作
2010-05-03 21:50
471 查看
九月 23rd, 2009发表评论阅读评论
最基本的数据结构还包括堆(Queue),也成为FIFO;很多消息驱动的系统中都有消息队列,一般的消息队列都是一个类似Queue的结构;下面我们来实现一个基本的Queue。
一般队列都包括一个队首指针和一个队尾指针,有的还包括一个队列有效长度的记录,然后每次出队和入队时调整队列长度,不过这种结构在多线程环境中会出现同步问题; 这里考虑用队首和队尾位置来确定队列的有效长度,为此,最大有效长度为n的队列的实际有效长度为[0,n],共计n+1个可能状态,因此队列的实际最大容量应为n+1,这样做的好处是,入队线程只需调整队尾的位置记录,出队线程只需调整队首的位置记录,在出队和入队前根据2个位置来判断是否可入队和出队。
一. 考虑堆的接口
除了常规的create,destroy,is_empty,is_full,length等之外,还包括:
enqueue(Queue, Element) 在队尾加入
dequeue(Queue, Element) 队首出列
二. 基于Cmockery先编写接口测试:
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
#include "./queue_array.h"
#ifdef WIN32
#pragma comment(lib, "D:/Code_Lib/cmockery/windows/cmockery.lib")
#endif
void create_test(void **state)
{
Queue qu = create(10);
assert_int_equal(length(qu), 0);
assert_false(!is_empty(qu));
destroy(qu);
}
void enqueue_test(void **state)
{
int i;
Queue qu = create(10);
for (i=0; i<10; i++)
{
enqueue(qu, i*10+1);
assert_int_equal(length(qu), i+1);
}
assert_false(!is_full(qu));
for (i=0; i<9; i++)
{
assert_int_equal(dequeue(qu), i*10+1);
assert_int_equal(length(qu), 9-i);
assert_int_equal(front(qu), i*10+11);
}
assert_int_equal(dequeue(qu), i*10+1);
assert_false(!is_empty(qu));
destroy(qu);
}
int main(int argc, char* argv[])
{
const UnitTest tests[]={
unit_test(create_test),
unit_test(enqueue_test),
};
return run_tests(tests);
};
三. 编写Queue接口:
// queue_array.h
/********************************************************************
created: 2009/09/23
created: 23:9:2009 13:35
filename: queue_array.h
file path: tdd_queue
file base: queue_array
file ext: h
author: wuyan
purpose: a queue struct which supported the reading and writting threads are separated.
*********************************************************************/
typedef int ElementType;
typedef struct TTQueue
{
int front; // the next reading element
int rear; // the last writted element
int capacity;
ElementType* data;
} TQueue;
typedef TQueue* Queue;
Queue create(int max_size);
void destroy(Queue qu);
int length(Queue qu);
int is_full(Queue qu);
int is_empty(Queue qu);
void enqueue(Queue qu, ElementType ele);
ElementType front(Queue qu);
ElementType dequeue(Queue qu);
四. 编写Queue实现:
#include "./queue_array.h"
#include "stdlib.h"
Queue create(int max_size)
{
Queue qu = malloc(sizeof(TQueue));
qu->data = malloc(sizeof(ElementType)*(max_size+1));
qu->capacity = max_size+1;
qu->front=1;
qu->rear=0;
return qu;
}
void destroy(Queue qu)
{
if (qu->data)
free(qu->data);
free(qu);
}
int length(Queue qu)
{
return ((qu->rear-qu->front+1+qu->capacity)%qu->capacity);
}
int is_full(Queue qu)
{
if (length(qu)+1 == qu->capacity)
return 1;
else
return 0;
}
int is_empty(Queue qu)
{
if (length(qu) == 0)
return 1;
else
return 0;
}
void enqueue(Queue qu, ElementType ele)
{
if (is_full(qu))
{
printf("the queue is full!/n");
return;
}
qu->rear = ((qu->rear+1) % qu->capacity);
qu->data[qu->rear] = ele;
}
ElementType front(Queue qu)
{
if (is_empty(qu))
{
printf("the queue is empty!/n");
return 0;
}
else
return qu->data[qu->front];
}
ElementType dequeue(Queue qu)
{
if (is_empty(qu))
{
printf("the queue is empty!/n");
return 0;
}
else
{
ElementType* ele = &qu->data[qu->front];
qu->front = ((qu->front+1) % qu->capacity);
return *ele;
}
}
最基本的数据结构还包括堆(Queue),也成为FIFO;很多消息驱动的系统中都有消息队列,一般的消息队列都是一个类似Queue的结构;下面我们来实现一个基本的Queue。
一般队列都包括一个队首指针和一个队尾指针,有的还包括一个队列有效长度的记录,然后每次出队和入队时调整队列长度,不过这种结构在多线程环境中会出现同步问题; 这里考虑用队首和队尾位置来确定队列的有效长度,为此,最大有效长度为n的队列的实际有效长度为[0,n],共计n+1个可能状态,因此队列的实际最大容量应为n+1,这样做的好处是,入队线程只需调整队尾的位置记录,出队线程只需调整队首的位置记录,在出队和入队前根据2个位置来判断是否可入队和出队。
一. 考虑堆的接口
除了常规的create,destroy,is_empty,is_full,length等之外,还包括:
enqueue(Queue, Element) 在队尾加入
dequeue(Queue, Element) 队首出列
二. 基于Cmockery先编写接口测试:
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
#include "./queue_array.h"
#ifdef WIN32
#pragma comment(lib, "D:/Code_Lib/cmockery/windows/cmockery.lib")
#endif
void create_test(void **state)
{
Queue qu = create(10);
assert_int_equal(length(qu), 0);
assert_false(!is_empty(qu));
destroy(qu);
}
void enqueue_test(void **state)
{
int i;
Queue qu = create(10);
for (i=0; i<10; i++)
{
enqueue(qu, i*10+1);
assert_int_equal(length(qu), i+1);
}
assert_false(!is_full(qu));
for (i=0; i<9; i++)
{
assert_int_equal(dequeue(qu), i*10+1);
assert_int_equal(length(qu), 9-i);
assert_int_equal(front(qu), i*10+11);
}
assert_int_equal(dequeue(qu), i*10+1);
assert_false(!is_empty(qu));
destroy(qu);
}
int main(int argc, char* argv[])
{
const UnitTest tests[]={
unit_test(create_test),
unit_test(enqueue_test),
};
return run_tests(tests);
};
三. 编写Queue接口:
// queue_array.h
/********************************************************************
created: 2009/09/23
created: 23:9:2009 13:35
filename: queue_array.h
file path: tdd_queue
file base: queue_array
file ext: h
author: wuyan
purpose: a queue struct which supported the reading and writting threads are separated.
*********************************************************************/
typedef int ElementType;
typedef struct TTQueue
{
int front; // the next reading element
int rear; // the last writted element
int capacity;
ElementType* data;
} TQueue;
typedef TQueue* Queue;
Queue create(int max_size);
void destroy(Queue qu);
int length(Queue qu);
int is_full(Queue qu);
int is_empty(Queue qu);
void enqueue(Queue qu, ElementType ele);
ElementType front(Queue qu);
ElementType dequeue(Queue qu);
四. 编写Queue实现:
#include "./queue_array.h"
#include "stdlib.h"
Queue create(int max_size)
{
Queue qu = malloc(sizeof(TQueue));
qu->data = malloc(sizeof(ElementType)*(max_size+1));
qu->capacity = max_size+1;
qu->front=1;
qu->rear=0;
return qu;
}
void destroy(Queue qu)
{
if (qu->data)
free(qu->data);
free(qu);
}
int length(Queue qu)
{
return ((qu->rear-qu->front+1+qu->capacity)%qu->capacity);
}
int is_full(Queue qu)
{
if (length(qu)+1 == qu->capacity)
return 1;
else
return 0;
}
int is_empty(Queue qu)
{
if (length(qu) == 0)
return 1;
else
return 0;
}
void enqueue(Queue qu, ElementType ele)
{
if (is_full(qu))
{
printf("the queue is full!/n");
return;
}
qu->rear = ((qu->rear+1) % qu->capacity);
qu->data[qu->rear] = ele;
}
ElementType front(Queue qu)
{
if (is_empty(qu))
{
printf("the queue is empty!/n");
return 0;
}
else
return qu->data[qu->front];
}
ElementType dequeue(Queue qu)
{
if (is_empty(qu))
{
printf("the queue is empty!/n");
return 0;
}
else
{
ElementType* ele = &qu->data[qu->front];
qu->front = ((qu->front+1) % qu->capacity);
return *ele;
}
}
相关文章推荐
- 基于Linux下开发的ELK自动部署工具以及ELK基本操作
- 循环队列和链式队列的结构及其基本操作(入队、出队、取队头、查看对内元素)
- 三维CAD建模——基于半边数据结构的基本欧拉操作建模
- 数据结构之二叉排序树(基于引用实现基本操作)
- 数据结构之二叉排序树(基于指针实现基本操作)
- 基于MapWinGis的开发探索(二)——注册、加载、基本操作
- 基于MapWinGis的开发探索(二)——注册、加载、基本操作
- 最新基于高德地图的android进阶开发(5)地图的基本操作、事件监听、用户UI、图层选择等
- 开发环境入门 linux基础 基本操作命令(部分) 文本结构和基本命令
- (转)基于MapWinGis开发探索(二)——注册、加载、基本操作
- 实战数据结构(5)_双向循环链表的基本操作
- 【学习总结】数据结构之循环链表的基本操作
- 实战数据结构(5)_双向循环链表的基本操作
- 数据结构(17)——基于邻接表的基本操作:构造,深搜(DFS),广搜(BFS)
- java mail邮件开发基本操作
- 一个基于python写的ms sql和postgresql互相转化表结构以及操作的用例
- 数据结构之一般树的基本操作
- lucene全文搜索之一:lucene的主要功能和基本结构(基于lucene5.5.3)
- C# window服务 开发、安装、启动、卸载、适应平台、自动循环操作数据库sqlserver完整版!
- 基于C++模板 单链表基本操作