自己写的Queue

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

### 实现队列数据结构 为了在 C# 中手动实现队列(Queue),可以创建一个类来表示队列并定义其基本操作方法。下面是一个简单的基于链表的队列实现: ```csharp public class Node { public int Data { get; set; } public Node Next { get; set; } public Node(int data) { Data = data; Next = null; } } public class Queue { private Node front; private Node rear; public Queue() { front = null; rear = null; } /// <summary> /// Adds an item to the end of the queue. /// </summary> /// <param name="item">Item to be added.</param> public void Enqueue(int item) { var newNode = new Node(item); if (rear == null) { front = rear = newNode; return; } rear.Next = newNode; rear = newNode; } /// <summary> /// Removes the first item from the queue and returns its value. /// If the queue is empty, throws InvalidOperationException. /// </summary> /// <returns>The removed item's value.</returns> public int Dequeue() { if (front == null) throw new System.InvalidOperationException("The queue is empty."); var tempNode = front; front = front.Next; if (front == null) rear = null; return tempNode.Data; } /// <summary> /// Returns true if the queue contains no items. /// </summary> /// <returns>True when there are no more items in this queue.</returns> public bool IsEmpty() => front == null; } ``` 上述代码展示了如何构建自定义 `Queue` 类及其核心功能——入队 (`Enqueue`) 和出队 (`Dequeue`) 方法[^1]。 #### 使用示例 这里提供了一个简单例子展示怎样使用这个新建立起来的手动版队列: ```csharp class Program { static void Main(string[] args) { var myQueue = new Queue(); // Adding some numbers into our custom-made queue foreach(var num in Enumerable.Range(1, 5)) { Console.WriteLine($"Adding {num}..."); myQueue.Enqueue(num); } // Removing all elements one-by-one until none left while (!myQueue.IsEmpty()) { try { Console.WriteLine($"Removed: {myQueue.Dequeue()}"); } catch(System.Exception ex) { Console.WriteLine(ex.Message); } } } } ``` 此程序片段会依次向队列中加入五个整数,之后再逐一移除这些数值直到队列为空为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值