顺序队列和链式队列

一,队列

上次讲到栈的插入删除在一端进行,那么这次我们要讲的队列是插入删除分别在两端进行,我们可以定义两个标识分别为插入标识(front)和删除标识(rear)。

在我们的循环队列中队满和队空都会使得rear==front,可以有很多代码逻辑来实现队满和队空的区分,比如我们可以定义一个flag变量,当rear因为入栈操作使得两者相等就可以变为1,因为出栈操作使得两者相等就可以变为0。但是由于多了一个变量会使得代码逻辑难度增加,就可以使用(front+1)%MAX==rear的操作判断队满的情况,配合if语句如果返回的是真那么表示队列已满,这样可以牺牲一个空间作为区分队满队空的依据

顺序队列和链式队列_第1张图片

二,队列的代码实现 

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判断是否有元素

顺序队列和链式队列_第2张图片

 四,链式队列代码实现

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;
}

你可能感兴趣的:(数据结构)