通用循环队列,这儿是我的笔记,希望大家可以友好交流!!谢谢#__#
有好几天没写了,一直和朋友玩,都没空看了。
今天得空写了一下队列的实现,还是和之前一样,有链表的方式和数组的方式两种。
先是数组的形式吧,队列结构:
struct XHqueue
{
int capacity;//由用户来定义容量大小
int len_queue;
int front;
int rear;
OPERATE callback;
void ** data;
};
队列一般实现为循环的,即有固定大小的,可以节省空间。这里仍然像实现栈那样,先动态分配一片固定大小的空间给队列。
数组式的实现接口如下:
#include<stdlib.h>
#include<stdio.h>
#include<memory.h>
typedef (*OPERATE)();
typedef enum
{
false = 0,
true,
}bool;
struct XHqueue;
typedef struct XHqueue XHQUEUE;
typedef struct XHqueue* XHQUEUE_T;
XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N);
bool Queue_IsEmpty(const XHQUEUE_T Que);
bool Queue_IsFull(const XHQUEUE_T);
void* Queue_Front(const XHQUEUE_T Que);//直插询
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data);
bool Queue_EnQueue(XHQUEUE_T Que,void* data);
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data);
int Queue_GetCapacity(XHQUEUE_T Que);
int Queue_GetLen(XHQUEUE_T Que);
#endif
XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N);
队列初始化时将front指向0,rear指向-1,因为每次入列前rear先加1;
bool Queue_IsEmpty(const XHQUEUE_T Que);
判空函数,判断标志由len是否为0(因为每次入列是len+1,出列时len-1)
bool Queue_IsFull(const XHQUEUE_T);
判满函数,capacity和len是否相等
void* Queue_Front(const XHQUEUE_T Que);
只查询队首元素
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data);
出队列函数,其实就是front+1;
bool Queue_EnQueue(XHQUEUE_T Que,void* data);
入队函数
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data);
删除整个队列,包括队列结构
int Queue_GetCapacity(XHQUEUE_T Que);
int Queue_GetLen(XHQUEUE_T Que);
接着实现的接口
#include"tongyongxunhuanduilie.h"
struct XHqueue
{
int capacity;//由用户来定义
int len_queue;
int front;
int rear;
OPERATE callback;
void ** data;
};
XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N)
{
Que = (XHQUEUE_T)malloc(sizeof(XHQUEUE));
if(Que == NULL) return NULL;
Que->data = (void**)malloc(sizeof(void*)*N);
if(Que->data==NULL)
{
free(Que);
return NULL;
}
else
{
Que->capacity = N;
Que->len_queue = 0;
Que->front = 0;
Que->rear = -1;
Que->callback = NULL;
return Que;
}
}
bool Queue_IsEmpty(const XHQUEUE_T Que)
{
if(Que == NULL) exit(0);
return Que->len_queue == 0 ? true : false;
}
bool Queue_IsFull(const XHQUEUE_T Que)
{
/**因为入队就+1,出队就减1,所以用size来*/
return Que->len_queue == Que->capacity ? true :false;
}
void* Queue_Front(const XHQUEUE_T Que)//只查询
{
if(Queue_IsEmpty(Que)) return NULL;
return Que->data[Que->front];
}
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data)
{
if(Queue_IsEmpty(Que)) return false;
if(op != NULL && data != NULL)
{
*data = Que->data[Que->front];
Que->callback = op;
Que->callback(*data);
}
Que->front = (Que->front++)%Que->capacity;
Que->len_queue--;
return true;
}
bool Queue_EnQueue(XHQUEUE_T Que,void* data)
{
if(Queue_IsFull(Que)) return false;
Que->rear =(Que->rear++)%Que->capacity;
Que->data[Que->rear] = data;
Que->len_queue++;
return true;
}
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data)
{
while(!Queue_IsEmpty(Que))
{
Queue_DeQueue(Que,op,data);
}
free(Que->data);
Que->data = NULL;
free(Que);
Que= NULL;
return true;
}
int Queue_GetCapacity(XHQUEUE_T Que)
{
if(Que == NULL) exit(0);
return Que->capacity;
}
int Queue_GetLen(XHQUEUE_T Que)
{
if(Que == NULL) exit(0);
return Que->len_queue;
}
以上是数组式的队列,我们还可以实现为链式循环队列
队列结构
struct node
{
void *data;
struct node* next;
};
struct XHqueue
{
int capacity;
int len;
struct node* front;
struct node* tail;
};
注意实现是带有头结点和尾结点(即这两个结点实际上是不存储data的,方便队列操作和实现的,所以容量实际比最大有效长度多2 ),因此,在访问队首元素是也是要用front->next来访问。
接口:
typedef (*OPERATE)();
typedef enum
{
false = 0,
true,
}bool;
struct node;
typedef struct node NODE;
typedef struct node* NODE_T;
struct Queue;
typedef struct XHqueue XHQUEUE;
typedef struct XHqueue* XHQUEUE_T;
XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N);
bool Queue_IsEmpty(const XHQUEUE_T Que);
bool Queue_IsFull(const XHQUEUE_T);
void* Queue_Front(const XHQUEUE_T Que);
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data);
bool Queue_EnQueue(XHQUEUE_T Que,void* data);
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data);
int Queue_GetCapacity(XHQUEUE_T Que);
int Queue_GetLen(XHQUEUE_T Que);
NODE_T Que_NodePOrevious(XHQUEUE_T Que,NODE_T nd);
#endif
功能从函数名称可以看出,还有具体的细节和前面几篇文章其实是相同的,所以直接上实现
#include"tongyongxunhuanlianshi.h"
struct node
{
void *data;
struct node* next;
};
/**发现还是要带头尾部节点比较好*/
struct XHqueue
{
int capacity;
int len;
struct node* front;
struct node* tail;
};
XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N)
{
if(N<0) return NULL;
Que = (XHQUEUE_T)malloc(sizeof(struct XHqueue));
if(Que==NULL) return NULL;
Que->capacity = N;
Que->len = 0;
Que->front = (NODE_T)malloc(sizeof(NODE));
Que->tail = (NODE_T)malloc(sizeof(NODE));
if(Que->front == NULL ||Que->tail == NULL)
{
free(Que);
Que = NULL;
return NULL;
}
Que->front->next = Que->tail;
Que->tail->next = Que->front;
Que->front->data = NULL;
Que->tail->data = NULL;
Que->len = 0 ;
return Que;
}
bool Queue_IsEmpty(const XHQUEUE_T Que)
{
if(Que == NULL) return false;
return Que->front->next== Que->tail&&Que->tail->next== Que->front ? true : false;
}
bool Queue_IsFull(const XHQUEUE_T Que)
{
if(!Queue_IsEmpty(Que))
{
return Que->len >= Que->capacity ? true : false;
}
return false;
}
void* Queue_Front(const XHQUEUE_T Que)
{
if(Queue_IsEmpty(Que)) NULL;
return Que->front->next->data;
}
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data)
{
NODE_T tmp = NULL;
if(Queue_IsEmpty(Que)) return false;
tmp = Que->front->next;
Que->front->next = tmp->next;
if(op!=NULL&&data!=NULL)
{
*data = tmp->data;
op(*data);
}
free(tmp);
tmp = NULL;
Que->len--;
return true;
}
bool Queue_EnQueue(XHQUEUE_T Que,void* data)
{
NODE_T newnode = (NODE_T)malloc(sizeof(NODE));
NODE_T pre = NULL;
if(newnode==NULL) return false;
newnode->data = data;
newnode->next = NULL;
if(Queue_IsFull(Que))
{
free(newnode);
newnode = NULL;
return false;
}
else
{
pre = Que_NodePOrevious(Que,Que->tail);
newnode->next = Que->tail;
pre->next = newnode;
Que->len++;
return true;
}
}
NODE_T Que_NodePOrevious(XHQUEUE_T Que,NODE_T nd)
{
NODE_T Head;
if(Que==NULL) return NULL;
Head = Que->front;
while(Head->next != Que->front)
{
if(Head->next == nd) return Head;
Head = Head->next;
}
if(Head->next != Que->front) return NULL;
}
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data)
{
if(Que == NULL) return false;
while(!Queue_IsEmpty(Que))
{
Queue_DeQueue(Que,op,data);
if(Queue_IsEmpty(Que)) break;
}
if(op!=NULL&&data!=NULL)
{
*data = Que->tail->data;
op(*data);
*data = Que->front->data;
op(*data);
}
free(Que->tail);
free(Que->front);
free(Que);
Que=NULL;
return true;
}
int Queue_GetCapacity(XHQUEUE_T Que)
{
if(Que == NULL) exit(0);
return Que->capacity;
}
int Queue_GetLen(XHQUEUE_T Que)
{
if(Que == NULL) exit(0);
return Que->len;
}
至此就完成两种方式的实现了!(线性数据结构终于看完了^_^)