代码如下:
SeqQueue.c文件:
/************************************************************************************
文件名:SeqQueue.c
头文件:SeqQueue.h
时间: 2014/03/31
作者: Hao
功能:可以复用的顺序循环队列 即入队列和出队列的时间复杂度都为O(1)
************************************************************************************/
#include
#include
#include "SeqQueue.h"
typedef void* TSeqQueueNode;
typedef struct str_SeqQueue
{
int capacity;
int length;
int front;
int rear;
TSeqQueueNode* node;
}TSeqQueue;
/************************************************************************************
函数名: SeqQueue_Create
函数功能: 创建一个容量为capacity的循环队列
参数: int capacity 创建循环队列中成员的个数 即循环队列容量
返回值: void* ret 如果返回NULL 说明创建循环队列失败
如果返回ret 说明创建循环队列成功 且ret为描述循环队列的结构体
************************************************************************************/
SeqQueue* SeqQueue_Create(int capacity)
{
TSeqQueue* ret = NULL;
if( capacity >= 0 )
{
ret = (TSeqQueue*)malloc(sizeof(TSeqQueue) + sizeof(TSeqQueueNode) * capacity);
if( ret != NULL )
{
ret->capacity = capacity;
ret->length = 0;
ret->front = 0;
ret->rear = 0;
ret->node = (TSeqQueueNode*)(ret + 1);
}
}
else
{
ret = NULL;
}
return (SeqQueue*)ret;
}
/************************************************************************************
函数名: SeqQueue_Destroy
函数功能: 销毁循环队列 free开辟的内存
参数: void* list 描述循环队列结构体指针
返回值: void
************************************************************************************/
void SeqQueue_Destroy(SeqQueue* queue)
{
free(queue);
}
/************************************************************************************
函数名: SeqQueue_Clear
函数功能:清空循环队列 其实就是给length=0; front = 0 rear = 0;
函数参数:SeqQueue* queue 描述循环队列结构体指针
函数返回值:int ret 成功返回0
失败返回-1
************************************************************************************/
int SeqQueue_Clear(SeqQueue* queue)
{
int ret;
TSeqQueue *Tqueue = (TSeqQueue* )queue;
/*函数参数合法性检测*/
if(NULL != Tqueue)
{
Tqueue->length = 0;
Tqueue->front = 0;
Tqueue->rear = 0;
ret=0;
}
else
ret=-1;
return ret;
}
/************************************************************************************
函数名: SeqQueue_Length
函数功能:获得循环队列 现在的大小
函数参数:void* list 描述循环队列结构体指针
函数返回值:int ret 成功返回length
失败返回-1
************************************************************************************/
int SeqQueue_Length(SeqQueue* queue)
{
int ret;
TSeqQueue *Tqueue = (SeqQueue* )queue;
/*函数参数合法性检测*/
if(NULL != Tqueue)
{
ret = Tqueue->length;
}
else
ret = -1;
return ret;
}
/************************************************************************************
函数名: SeqQueue_Capacity
函数功能:获得循环队列 的容量
函数参数:void* list 描述循环队列结构体指针
函数返回值:int ret 成功返回capacity
失败返回-1
************************************************************************************/
int SeqQueue_Capacity(SeqQueue* queue)
{
int ret;
TSeqQueue *Tqueue = (SeqQueue* )queue;
/*函数参数合法性检测*/
if(NULL != Tqueue)
{
ret = Tqueue->capacity;
}
else
ret = -1;
return ret;
}
/************************************************************************************
函数名: SeqQueue_Push
函数功能:入队操作
函数参数:SeqQueue* queue入队队列, void* data入队数据元素
这个队列是从尾部入队rear 从头部出队front
函数返回值:int ret 成功返回 1
失败返回 0
************************************************************************************/
int SeqQueue_Push(SeqQueue* queue, void* data)
{
TSeqQueue* Tqueue = (TSeqQueue*)queue;
int ret = (Tqueue != NULL) && (data != NULL); //安全性检测
ret = ret && (Tqueue->length + 1 <= Tqueue->capacity); //容量检测
if(ret)
{
Tqueue->node[Tqueue->rear] = data;
Tqueue->rear = (Tqueue->rear + 1) % Tqueue->capacity;
Tqueue->length++;
}
return ret;
}
/************************************************************************************
函数名: SeqQueue_Pop
函数功能:出队操作
函数参数:SeqQueue* queue出队队列
这个队列是从尾部入队rear 从头部出队front
函数返回值:void* ret 成功返回 数据元素地址
失败返回 NULL
************************************************************************************/
void* SeqQueue_Pop(SeqQueue* queue)
{
TSeqQueue* Tqueue = (TSeqQueue*)queue;
void* ret = NULL;
if((Tqueue != NULL) && (Tqueue->length > 0))
{
ret = (void*)(Tqueue->node[Tqueue->front]);
Tqueue->front = (Tqueue->front + 1) % Tqueue->capacity;
Tqueue->length--;
}
return ret;
}
/************************************************************************************
函数名: SeqQueue_Top
函数功能:获得队尾元素地址
函数参数:SeqQueue* queue出队队列
这个队列是从尾部入队rear 从头部出队front
函数返回值:void* ret 成功返回 队尾数据元素地址
失败返回 NULL
************************************************************************************/
void* SeqQueue_Top(SeqQueue* queue)
{
TSeqQueue* Tqueue = (TSeqQueue*)queue;
void* ret = NULL;
if((Tqueue != NULL) && (Tqueue->length > 0))
{
ret = (void*)(Tqueue->node[Tqueue->front]);
}
return ret;
}
#ifndef _SeqQueue_H_
#define _SeqQueue_H_
typedef void SeqQueue;
SeqQueue* SeqQueue_Create(int capacity);
void SeqQueue_Destroy(SeqQueue* queue);
int SeqQueue_Clear(SeqQueue* queue);
int SeqQueue_Push(SeqQueue* queue, void* data);
void* SeqQueue_Pop(SeqQueue* queue);
void* SeqQueue_Top(SeqQueue* queue);
int SeqQueue_Length(SeqQueue* queue);
int SeqQueue_Capacity(SeqQueue* queue);
#endif
#include
#include
#include "SeqQueue.h"
int main(int argc, char *argv[])
{
SeqQueue* queue = SeqQueue_Create(6);
int a[10] = {0};
int i = 0;
for(i=0; i<10; i++)
{
a[i] = i + 1;
SeqQueue_Push(queue, a + i);
}
printf("Top: %d\n", *(int*)SeqQueue_Top(queue));
printf("Length: %d\n", SeqQueue_Length(queue));
printf("Capacity: %d\n", SeqQueue_Capacity(queue));
while( SeqQueue_Length(queue) > 0 )
{
printf("Pop: %d\n", *(int*)SeqQueue_Pop(queue));
}
printf("\n");
for(i=0; i<10; i++)
{
a[i] = i + 1;
SeqQueue_Push(queue, a + i);
printf("Pop: %d\n", *(int*)SeqQueue_Pop(queue));
}
SeqQueue_Destroy(queue);
return 0;
}
注意:其实循环队列就是在一段内存空间中,使用front和rear变量夹住一端空间,使其成为顺序队列,并且入队列和出队列的时间复杂度都是O(1)
示例代码:
LinkQueue.c文件:
/*******************************************************************************************************
文件名:LinkQueue.c
头文件:LinkQueue.h
时间: 2013/03/31
作者: Hao
功能: 可以复用 链式队列
*******************************************************************************************************/
#include
#include
#include "LinkQueue.h"
typedef struct str_linkqueue
{
LinkQueueNode* front;
LinkQueueNode* rear;
int length;
}link_queue;
/*******************************************************************************************************
函数名: Creat_LinkQueueHead
函数功能:创建一个链式队列头 并给队列头分配空间
参数: void
返回值:ret 成功返回链表头地址 失败返回NULL
*******************************************************************************************************/
LinkQueue* Creat_LinkQueueHead(void)
{
link_queue* ret = NULL;
ret = (link_queue* )malloc( sizeof(link_queue)*1 );
if(NULL != ret) //malloc分配成功
{
ret -> length = 0;
ret -> front = NULL;
ret -> rear = NULL;
}
return (LinkQueue* )ret;
}
/*******************************************************************************************************
函数名: Get_Length
函数功能:获得链式队列的长度
参数: LinkQueue* queue 描述队列的结构体
返回值:ret 成功返回队列长度 失败返回0
*******************************************************************************************************/
int Get_Length(LinkQueue* queue)
{
int ret = 0;
link_queue* lqueue = (link_queue* )queue;
if( NULL != lqueue )
{
ret = lqueue -> length;
}
return ret;
}
/*******************************************************************************************************
函数名: LinkQueue_Push
函数功能:把数据data从队尾加入队列中
参数: LinkQueue* queue 描述队列的结构体 void* data 要加入队列数据的地址
返回值:ret 成功返回1 失败返回0
*******************************************************************************************************/
int LinkQueue_Push(LinkQueue* queue, void* data)
{
link_queue* lqueue = (link_queue* )queue;
int ret = ((NULL != lqueue)&&(NULL != data));
if(ret)
{
LinkQueueNode* node = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if(NULL != node)
{
node -> Queuedata = data;
if(lqueue -> length == 0)
{
lqueue -> front = node;
lqueue -> rear = node;
node -> next = NULL;
}
else
{
lqueue -> rear -> next = node;
lqueue -> rear = node;
node -> next = NULL;
}
lqueue -> length++;
}
}
return ret;
}
/*******************************************************************************************************
函数名: LinkQueue_Pop
函数功能:把数据从队头取出
参数: LinkQueue* queue 描述队列的结构体
返回值:ret 成功返回取出数据地址 失败返回NULL
*******************************************************************************************************/
void* LinkQueue_Pop(LinkQueue* queue)
{
void* ret = NULL;
LinkQueueNode* node = NULL;
link_queue* lqueue = (link_queue* )queue;
if((NULL != lqueue)&&(lqueue->length > 0))
{
node = lqueue->front;
lqueue->front = lqueue->front->next;
lqueue->length--;
ret = node->Queuedata;
free(node);
if(lqueue->length == 0)
{
lqueue->front = NULL; //其实理论上可以不给front赋值NULL的
lqueue->rear = NULL;
}
}
return ret;
}
/*******************************************************************************************************
函数名: LinkQueue_Top
函数功能:获得队头数据地址
参数: LinkQueue* queue 描述队列的结构体
返回值:ret 成功返回取出数据地址 失败返回NULL
*******************************************************************************************************/
void* LinkQueue_Top(LinkQueue* queue)
{
void* ret = NULL;
link_queue* lqueue = (link_queue* )queue;
if((NULL != lqueue)&&(lqueue->length > 0))
{
ret = lqueue->front->Queuedata;
}
return ret;
}
/*******************************************************************************************************
函数名: Clean_LinkQueue
函数功能:清空队列
参数: LinkQueue* queue 描述队列的结构体
返回值:ret 成功返回1 失败返回0
*******************************************************************************************************/
int Clean_LinkQueue(LinkQueue* queue)
{
int ret = 0;
void* temp = NULL;
if(NULL != queue)
{
ret = 1;
while(Get_Length(queue))
{
temp = LinkQueue_Pop(queue);
if(NULL == temp)
{
ret = 0;
break;
}
}
}
return ret;
}
/*******************************************************************************************************
函数名: Destroy_LinkQueue
函数功能:清空队列并且销毁队列头
参数: LinkQueue* queue 描述队列的结构体
返回值:ret 成功返回1 失败返回0
*******************************************************************************************************/
void Destroy_LinkQueue(LinkQueue* queue)
{
Clean_LinkQueue(queue);
free(queue);
}
#ifndef __LinkQueue_H__
#define __LinkQueue_H__
typedef void LinkQueue; //这个是为了 封装方便
typedef struct Str_LinkQueue LinkQueueNode; //这个结构体是链表的真身
struct Str_LinkQueue
{
LinkQueueNode* next;
void* Queuedata;
};
LinkQueue* Creat_LinkQueueHead(void);
void Destroy_LinkQueue(LinkQueue* queue);
int Get_Length(LinkQueue* queue);
int Clean_LinkQueue(LinkQueue* queue);
int LinkQueue_Push(LinkQueue* queue, void* data);
void* LinkQueue_Pop(LinkQueue* queue);
void* LinkQueue_Top(LinkQueue* queue);
#endif
#include
#include "LinkQueue.h"
int main()
{
LinkQueue* queue = Creat_LinkQueueHead();
int a[10] = {0};
int i = 0;
for(i=0; i<10; i++)
{
a[i] = i + 1;
LinkQueue_Push(queue, a + i);
}
printf("Pop: %d\n", *(int*)LinkQueue_Pop(queue));
printf("Top: %d\n", *(int*)LinkQueue_Top(queue));
printf("Length: %d\n", Get_Length(queue));
//Clean_LinkQueue(queue);
while( Get_Length(queue) > 0 )
{
printf("Pop: %d\n", *(int*)LinkQueue_Pop(queue));
}
Destroy_LinkQueue(queue);
return 0;
}
注意:链队列,无非就是定义了两个指针,分别指向队列头和队列尾,这样找到队头和队尾的时间复杂度就是O(1)