一,队列
上次讲到栈的插入删除在一端进行,那么这次我们要讲的队列是插入删除分别在两端进行,我们可以定义两个标识分别为插入标识(front)和删除标识(rear)。
在我们的循环队列中队满和队空都会使得rear==front,可以有很多代码逻辑来实现队满和队空的区分,比如我们可以定义一个flag变量,当rear因为入栈操作使得两者相等就可以变为1,因为出栈操作使得两者相等就可以变为0。但是由于多了一个变量会使得代码逻辑难度增加,就可以使用(front+1)%MAX==rear的操作判断队满的情况,配合if语句如果返回的是真那么表示队列已满,这样可以牺牲一个空间作为区分队满队空的依据
二,队列的代码实现
1,头文件中的接口
#ifndef COMMON_H
#define COMMON_H
typedef int Element;
#endif //COMMON_H
#ifndef ARRAYQUEUE_H
#define ARRAYQUEUE_H
#define MAXSIZE 5
#include "common.h"
typedef int Element;
typedef struct {
Element data[MAXSIZE];
int front;
int rear;
}ArrayQueue;
void initArrayQueue(ArrayQueue*queue);
int enArrayQueue(ArrayQueue*queue,Element e);
int deArrayQueue(ArrayQueue*queue,Element*e);
#endif //ARRAYQUEUE_H
2,将头文件中的接口一一实现
#include
#include "arrayQueue.h"
void initArrayQueue(ArrayQueue *queue) {
queue->rear=queue->front=0;
}
int enArrayQueue(ArrayQueue *queue, Element e) {
if ((queue->rear+1)%MAXSIZE==queue->front) {
fprintf(stderr,"Queue is full\n");
return -1;
}
queue->data[queue->rear]=e;
queue->rear=(queue->rear+1)%MAXSIZE;
return 0;
}
int deArrayQueue(ArrayQueue *queue, Element *e) {
if (queue->rear%MAXSIZE==queue->front) {
fprintf(stderr,"Queue is empty\n");
return -1;
}
*e=queue->data[queue->front];
queue->front=(queue->front+1)%MAXSIZE;
return 0;
}
3,测试写好的代码是否有bug
#include
#include "arrayQueue.h"
void test() {
ArrayQueue queue;
initArrayQueue(&queue);
//1
for(int i=0;i<4;i++) {
enArrayQueue(&queue,100+i);
}
enArrayQueue(&queue,500);
Element e;
while (deArrayQueue(&queue,&e)!=-1) {
printf("%d\t",e);
}
printf("\n");
}
int main() {
test();
return 0;
}
三,链式队列
链式队列也需要插入标识(front)和删除标识(rear),只是所有元素放在了节点结构,链式队列在入栈的时候是往rear的next方向插入,因为如果像链式栈一样往反方向插入,删除的时候就会找不到下一节点
在插入的时候需要调用rear指向节点的成员,但我们初始化的时候rear指向的是NULL,因此插入逻辑中需要使用if判断是否有元素
四,链式队列代码实现
1.头文件中的接口
#ifndef LINKQUEUE_H
#define LINKQUEUE_H
#include "common.h"
typedef struct _node {
Element data;
struct _node*next;
}node_t;
typedef struct {
node_t*front;
node_t*rear;
char*name;
int count;
}linkQueue_t;
linkQueue_t*createLinkQueue(const char* name);
int enLinkQueue(linkQueue_t*queue,Element data);
int deLinkQueue(linkQueue_t*queue,Element*data);
void releaseLinkQueue(linkQueue_t*queue);
#endif //LINKQUEUE_H
2.将头文件中的接口一一实现
#include
#include
#include "common.h"
#include "linkQueue.h"
linkQueue_t * createLinkQueue(const char *name) {
linkQueue_t*queue=malloc(sizeof(linkQueue_t));
queue->name=name;
queue->front=queue->rear=NULL;
queue->count=0;
return queue;
}
int enLinkQueue(linkQueue_t *queue, Element data) {
node_t*newnode=malloc(sizeof(node_t));
newnode->data=data;
newnode->next=NULL;
if (queue->front==NULL) {
queue->front=queue->rear=newnode;
}else {
queue->rear->next=newnode;
queue->rear=newnode;
}
queue->count++;
return -1;
}
int deLinkQueue(linkQueue_t *queue,Element*data) {
if (queue->front==NULL) {
fprintf(stderr,"linkQueue is empty\n");
return 0;
}
node_t*temp=queue->front;
*data=temp->data;
queue->front=temp->next;
free(temp);
queue->count--;
return -1;
}
void releaseLinkQueue(linkQueue_t *queue) {
while (queue->front!=NULL) {
node_t*temp=queue->front;
queue->front=temp->next;
free(temp);
queue->count--;
}
free(queue);
}
3.测试代码是否有bug
#include
#include "arrayQueue.h"
#include "linkQueue.h"
void test2() {
linkQueue_t*queue=createLinkQueue("stu");
for (int i=0;i<5;i++) {
enLinkQueue(queue,100+i);
}
Element e;
while (deLinkQueue(queue,&e)) {
printf("%d\t",e);
}
printf("\n");
releaseLinkQueue(queue);
}
int main() {
//test();
test2();
return 0;
}