自己写的Queue

这是一个C语言实现的Queue数据结构,包含Queue的内存大小计算、初始化、清零、计数、判断满和空、Push和Pop操作。还包含了单元测试代码,用于验证Queue的正确性和性能。
摘要由CSDN通过智能技术生成
CAlgQueue.h

#ifndef _C_ALG_QUEUE_H_
#define _C_ALG_QUEUE_H_
#include <stdlib.h>
#include <string.h>
#include "CAlgCommon.h"

#ifdef	__cplusplus
extern "C" {
#endif

typedef struct {
	unsigned int head;
	unsigned int tail;

	unsigned int max_count;  //q_arrary[0...max_count-1], queue can only hold max-1 items
	unsigned int elem_size;
#ifdef WIN32
#pragma warning(disable:4200)
#endif
	unsigned char q_arrary[0];
#ifdef WIN32
#pragma warning(default:4200)
#endif
}CAlgQueue;

static inline unsigned int CAlgQueue_MemSize(unsigned int elem_size, unsigned int max_count)
{
	return sizeof(CAlgQueue) + elem_size * max_count;
}

static inline void CAlgQueue_Reset(CAlgQueue* q, unsigned int elem_size, unsigned int max_count)
{
	q->head = q->tail = 0;
	q->max_count = max_count;
	q->elem_size = elem_size;
}

static inline unsigned int CAlgQueue_Count(CAlgQueue* q)
{
	return (q->head + q->max_count - q->tail)%(q->max_count);
}

static inline int CAlgQueue_IsFull(CAlgQueue* q)
{
	return ((q->head + 1) % (q->max_count)) == q->tail;
}

static inline int CAlgQueue_IsEmpty(CAlgQueue* q)
{
	return q->head == q->tail;
}

static inline int CAlgQueue_Push(CAlgQueue* q, void* e)
{
	unsigned int rc = -1;
	if(CAlgQueue_IsFull(q)) return rc;
	rc = q->head;
	memcpy(& q->q_arrary[q->elem_size * rc], e, q->elem_size);
	q->head = (rc + 1) % q->max_count;
	return rc ;
}

static inline int CAlgQueue_Pop(CAlgQueue* q, void* e)
{
	unsigned int rc = -1;
	if(CAlgQueue_IsEmpty(q)) return rc;
	rc = q->tail;
	memcpy(e, & q->q_arrary[q->elem_size * rc], q->elem_size);
	q->tail = (rc + 1) % q->max_count;
	return rc ;
}

#ifdef	__cplusplus
}
#endif

#endif
//end of file

单元测试:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "CAlgQueue.h"

#define MAX_QUEUE_NODE_ELEM   10000000
typedef struct {
	int a;
	int b;
}CAlgQueueData;

static CAlgQueue* g_AlgQueue;

void TestAlgQueue_Init()
{
	g_AlgQueue = (CAlgQueue*)malloc(CAlgQueue_MemSize(sizeof(CAlgQueueData),MAX_QUEUE_NODE_ELEM));
	CAlgQueue_Reset(g_AlgQueue,sizeof(CAlgQueueData),MAX_QUEUE_NODE_ELEM);
}

void TestAlgQueue_Free()
{
	free(g_AlgQueue);
}

void TestAlgQueue_Push_Pop()
{
	int i;
	CAlgQueueData qd ;

	//queue is empty
	assert(CAlgQueue_IsEmpty(g_AlgQueue));
	assert(!CAlgQueue_IsFull(g_AlgQueue));
	assert(CAlgQueue_Pop(g_AlgQueue, &qd) == -1);

	//
	//test queue push to full
	for(i=0; i<MAX_QUEUE_NODE_ELEM-1; i++)
	{
		qd.a = 1000+i;
		qd.b = 1001+i;
		assert(!CAlgQueue_IsFull(g_AlgQueue));
		assert(i == CAlgQueue_Push(g_AlgQueue, (void*)&qd));
		assert(!CAlgQueue_IsEmpty(g_AlgQueue));
		assert(CAlgQueue_Count(g_AlgQueue) == i+1);
	}

	//queue is full
	assert(CAlgQueue_Count(g_AlgQueue) == MAX_QUEUE_NODE_ELEM-1);
	assert(CAlgQueue_IsFull(g_AlgQueue));
	//queue is full and push return -1
	assert(-1 == CAlgQueue_Push(g_AlgQueue, &qd));
	assert(g_AlgQueue->head == MAX_QUEUE_NODE_ELEM-1);
	assert(g_AlgQueue->tail == 0);

	//
	//test queue pop to empty
	i=0;
	while(CAlgQueue_Pop(g_AlgQueue, &qd) != -1)
	{
		assert(qd.a == 1000+i);
		assert(qd.b == 1001+i);
		i++;
	}
	assert(i == MAX_QUEUE_NODE_ELEM-1);
	assert(CAlgQueue_Count(g_AlgQueue) == 0u);
	assert(!CAlgQueue_IsFull(g_AlgQueue));
	assert(CAlgQueue_IsEmpty(g_AlgQueue));
	assert(g_AlgQueue->head == MAX_QUEUE_NODE_ELEM-1);
	assert(g_AlgQueue->tail == MAX_QUEUE_NODE_ELEM-1);


	//
	//head and tail are point to MAX_QUEUE_NODE_ELEM - 1
	//push and pop another 5 nodes
	for(i=0; i<5; i++)
	{
		qd.a = 500+i;
		qd.b = 501+i;
		assert(((MAX_QUEUE_NODE_ELEM - 1 + i)%MAX_QUEUE_NODE_ELEM)
			== CAlgQueue_Push(g_AlgQueue, (void*)&qd));
	}
	assert(!CAlgQueue_IsFull(g_AlgQueue));
	assert(!CAlgQueue_IsEmpty(g_AlgQueue));
	assert(CAlgQueue_Count(g_AlgQueue) == 5u);
	assert(g_AlgQueue->head == 4);

	i=0;
	while(CAlgQueue_Pop(g_AlgQueue, &qd) != -1)
	{
		assert(qd.a == 500+i);
		assert(qd.b == 501+i);
		i++;
	}
	assert(i == 5);
	assert(!CAlgQueue_IsFull(g_AlgQueue));
	assert(CAlgQueue_IsEmpty(g_AlgQueue));
	assert(CAlgQueue_Count(g_AlgQueue) == 0u);
	assert(g_AlgQueue->tail == 4);

}

#include <Windows.h>
void TestAlgQueue_Run()
{
	SYSTEMTIME st1, st2;
	FILETIME ft1, ft2; //100ns

	TestAlgQueue_Init();

	GetLocalTime(&st1);
	TestAlgQueue_Push_Pop();
	GetLocalTime(&st2);
	SystemTimeToFileTime(&st1, &ft1);
	SystemTimeToFileTime(&st2, &ft2);
	printf("%s using %u.%03ums to push/pop %d nodes %02u:%02u:%02u.%03u - %02u:%02u:%02u.%03u\n", 
		__FILE__,
		(ft2.dwLowDateTime-ft1.dwLowDateTime)/10000,
		(ft2.dwLowDateTime-ft1.dwLowDateTime)/10, MAX_QUEUE_NODE_ELEM,
		st1.wHour,st1.wMinute,st1.wSecond,st1.wMilliseconds,
		st2.wHour,st2.wMinute,st2.wSecond,st2.wMilliseconds);

	TestAlgQueue_Free();
}
//end of file

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值