首先来看一下百度百科关于队列的介绍:
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列满足先进先出(FIFO)的原则,我们可以用链表的尾插头删模拟队列,还可以用顺序表实现循环队列。
下面介绍一下循环栈:
seqqueue.h
#include
#include
#define TestType printf("\n###################### %s #########################\n",__FUNCTION__)
//设置最大数量 4,这样设置是为了在后面的测试中方便模拟达到最大元素的状态
#define SeqQueueMaxSize 4
typedef char SeqQueueType;
typedef struct SeqQueue{
SeqQueueType data[SeqQueueMaxSize];
size_t head;
size_t tail;
size_t size;
} SeqQueue;
//初始化函数
void SeqQueueInit(SeqQueue* q);
//入队列函数
void SeqQueuePush(SeqQueue* q,SeqQueueType value);
//出队列函数
void SeqQueuePop(SeqQueue* q);
//打印函数
void SeqQuquqPrint(SeqQueue* q,const char* msg);
//取对手元素
int SeqQueueFront(SeqQueue* q,SeqQueueType* value);
seqqueue.c
#include"seqqueue.h"
void SeqQueueInit(SeqQueue* q){
if(q == NULL){
return;
}
q->tail = 0;
q->head = 0;
q->size = 0;
return;
}
void SeqQueuePush(SeqQueue* q,SeqQueueType value){
if(q == NULL){
return;
}
if(q->size >= SeqQueueMaxSize){
return;
}
q->data[q->tail++] = value;
if(q->tail >= SeqQueueMaxSize){
//如果队列的tail号下标达到最大值,下一个元素在数组的0号元素插入
q->tail = 0;
}
q->size++;
}
void SeqQueuePop(SeqQueue* q){
if(q == NULL){
return;
}
if(q->size == 0){
return;
}
q->head++;
if(q->head >= SeqQueueMaxSize){
q->head = 0;
}
q->size--;
}
//打印函数
void SeqQuquqPrint(SeqQueue* q,const char* msg){
if(q == NULL){
return;
}
printf("[ %s ]:\n",msg);
int i = q->tail - 1;
int count = q->size - 1;
打印tail开始的count个元素
while(count--){
if(i >= 0){
printf("%c->",q->data[i--]);
}else{
i = SeqQueueMaxSize - 1;
printf("%c->",q->data[i--]);
}
}
printf("%c\n",q->data[q->head]);
return;
}
//取队首元素,这里的value是输出型参数
int SeqQueueFront(SeqQueue* q,SeqQueueType* value){
if(q == NULL){
return 0;
}
if(q->size == 0){
return 0;
}
*value = q->data[q->head];
return 1;
}
main.c
#include"seqqueue.h"
void TestSeqQueuePush(){
TestType;
SeqQueue q;
SeqQueueInit(&q);
SeqQueuePush(&q,'a');
SeqQueuePush(&q,'b');
SeqQueuePush(&q,'c');
SeqQueuePush(&q,'d');
// SeqQueuePush(&q,'e');
SeqQuquqPrint(&q,"abcde入队列");
SeqQueuePop(&q);
SeqQuquqPrint(&q,"a出队列");
SeqQueuePop(&q);
SeqQuquqPrint(&q,"b出队列");
SeqQueuePush(&q,'e');
SeqQuquqPrint(&q,"e入队列");
return;
}
void TestSeqQueueFront(){
TestType;
SeqQueueType value;
SeqQueue q;
SeqQueueInit(&q);
SeqQueuePush(&q,'a');
SeqQueuePush(&q,'b');
SeqQueuePush(&q,'c');
SeqQueuePush(&q,'d');
int ret = SeqQueueFront(&q,&value);
printf("expect: 1 , actual:%d\n",ret);
printf("expect: a , actual:%c\n",value);
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePush(&q,'e');
SeqQuquqPrint(&q,"ab出队列,e入队列");
ret = SeqQueueFront(&q,&value);
printf("expect: 1 , actual:%d\n",ret);
printf("expect: c , actual:%c\n",value);
return;
}
int main(){
TestSeqQueuePush();
TestSeqQueueFront();
return 0;
}
上面就是用顺序表模拟队列的实现过程。
下面来介绍一下,链式队列
linkqueue.c
#pragma once
#include
#include
#include
#define TestType printf("\n################################## %s #################################\n",__FUNCTION__)
#define LinkQueueType char
typedef struct LinkNode{
struct LinkNode* next;
LinkQueueType data;
} LinkNode;
typedef struct LinkQueue{
struct LinkNode* head;
struct LinkNode* tail;
} LinkQueue;
//初始化函数
void LinkQueueInit(LinkQueue* q);
//入队列函数
void LinkQueuePush(LinkQueue* q,LinkQueueType value);
//打印函数
void LinkQueuePrint(LinkQueue* q,const char* msg);
//出队列函数
void LinkQueuePop(LinkQueue* q);
//取队首元素
int LinkQueueFront(LinkQueue* q,LinkQueueType* value);
linkqueue.c
#include"linkqueue.h"
void LinkQueueInit(LinkQueue* q){
if(q == NULL){
return;
}
q->head = NULL;
q->tail = NULL;
return;
}
LinkNode* LinkQueueCreateNode(LinkQueueType value){
LinkNode* new_node = (LinkNode*)malloc(sizeof(LinkNode));
if(new_node == 0){
return NULL;
}
new_node->next = NULL;
new_node->data = value;
return new_node;
}
void DestroyNode(LinkNode* to_delete){
if(to_delete == NULL){
return;
}
free(to_delete);
return;
}
void LinkQueuePush(LinkQueue* q,LinkQueueType value){
if(q == NULL){
return;
}
LinkNode* new_node = LinkQueueCreateNode(value);
if(q->head == NULL){
q->head = new_node;
q->tail = new_node;
return;
}
q->tail->next = new_node;
q->tail = q->tail->next;
return;
}
void LinkQueuePrint(LinkQueue* q,const char* msg){
if(q == NULL){
return;
}
printf("[ %s ]:\n",msg);
LinkNode* cur = q->head;
while(cur != NULL){
printf("[%c][%p]<-",cur->data,cur);
cur = cur->next;
}
printf("NULL\n\n");
return;
}
void LinkQueuePop(LinkQueue* q){
if(q == NULL){
return;
}
if(q->head == NULL){
return;
}
LinkNode* temp = q->head;
q->head = q->head->next;
DestroyNode(temp);
return;
}
int LinkQueueFront(LinkQueue* q,LinkQueueType* value){
if(q == NULL){
return 0;
}
*value = q->head->data;
return 1;
}
以上就是关于链式队列的介绍。
由于我的能力有限,上面的介绍可能有不妥或者Bug,欢迎发邮件到我的邮箱([email protected])批评指正!