我们今天来学习队列,这个博客我写的是链式队列
首先我们来了解一下什么是队列
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列有两种实现方式,他跟栈极其相似,只不过他是先进先出,顾名思义,他就跟我们现实排队是一模一样的。跟栈一样,两种实现方式,一种是链式队列,一种是数组队列
链式队列的实现方式就是无头链表的头删除法,和尾插入法。
首先我们做好准备工作:1.节点结构体 2.创建节点函数 3.封装队列的结构体4.创建队列函数 5.两个万金油函数(查询大小,查询是否为空)
struct node {
int data;
struct node* next;
};
struct node* createnode(int data) {
struct node* newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
创建节点,不用多说,看我文章的兄弟相必非常熟悉了
struct queue {
int size;
struct node* queuehead;
struct node* queueend;
};
struct queue* createqueue() {
struct queue* newqueue = (struct queue*)malloc(sizeof(struct queue));
newqueue->size = 0;
newqueue->queuehead = newqueue->queueend = NULL;
return newqueue;
}
这个封装队列,看我文章的兄弟一定会说,这里是不是跟我最开始封装链表的那个结构体好相似,对的,队列也是包含了这三个特点,大小,队头,队尾,所以就这样封装队列
int sizeofq(struct queue* pqueue) {
return pqueue->size;
}
bool empty(struct queue* pqueue) {
return pqueue->size == 0;
}
两个万金油函数
下面实现入队(push)
void push(struct queue* pqueue, int data) {
struct node* newnode = createnode(data);
if (empty(pqueue)) {
pqueue->queuehead = newnode;
}
else {
pqueue->queueend->next = newnode;
}
pqueue->queueend = newnode;
pqueue->size++;
}
其实也没什么新的知识点,也就是无头链表的尾插入
下面实现出队(pop)也就是删除队头元素
void pop(struct queue* pqueue) {
if (empty(pqueue)) {
printf("空队列无法出列新元素");
}
else {
struct node* deletenode = pqueue->queuehead;
if (sizeofq(pqueue) == 1) {
pqueue->queueend = pqueue->queuehead = NULL;
}
else {
pqueue->queuehead = deletenode->next;
}
free(deletenode);
pqueue->size--;
}
}
也是没新的知识点,也就是无头链表的头删除
下面实现队头元素获取:
int out(struct queue* pqueue) {
if (empty(pqueue)) {
printf("空队列");
exit(0);
}
return pqueue->queuehead->data;
}
这里强调的就是空队列处理情况,别访问出错了
下面就来检验一下我们的队列实现情况:
int main() {
struct queue* myqueue = createqueue();
push(myqueue, 3);
push(myqueue, 2);
push(myqueue, 1);
push(myqueue, 0);
while (1) {
printf("%d\t", out(myqueue));
pop(myqueue);
}
return 0;
}
这里我要说的是为什么,我敢while(1),是因为我在查询队头函数里面写了一个队空处理的情况exit()直接退出函数,所以不会出错或者再输出一个0或者其他数;如果你不会处理,就改成while(empty(myqueue))也行。
好了链式队列就到这了,下个文章我实现一下数组队列(会比这个简单哦)。