前言:在实现栈之后我们再介绍一下他的孪生兄弟,一个是后进先出,一个是先进先出。那么就让我们来详细的了解一下队列把。
目录
一.队列概念
二.队列的实现
1.定义队列
2.初始化队列
3.入队
4.判断队列是否为空
5.出队
6.返回队头和队尾
7.查看队尾内容
8.查看队列数量
9.销毁队列
三.队列实现所有代码
四.结言
一.队列概念
队列:
只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
在数组内实现避免不了有数据的移动,比如将a0当队头插入队列时进行尾插,但是在每次出队的时候需要将后面的数据向前移动一位,这就不免是(n-1)的时间复杂度。
而将an做位队头那么每次插入时又需要挪动数据,时间复杂度也是(n-1),所以我们采用链表的方式实现就很方便。
二.队列的实现
1.定义队列
typedef int QEtype;typedef struct QEnode{QEtype val;struct QEnode *next;
}QEnode;typedef struct QE
{QEnode* head;QEnode* tail;int size;
}QE;
这里我们把队列的队头,队尾以及队列的长度记录下来。这样会对我们进行的操作有很大的便利。
2.初始化队列
void QEInit(QE* qe)
{assert(qe);qe->head = NULL;qe->tail = NULL;qe->size = 0;
}
3.入队
void QEPush(QE* qe, QEtype x)
{assert(qe);QEnode* newnext = (QEnode*)malloc(sizeof(QEnode));if (newnext == NULL){perror(malloc);return;}newnext->next = NULL;newnext->val = x;if (qe->size == 0){qe->head = qe->tail = newnext;}else{qe->tail->next = newnext;qe->tail = newnext;}qe->size++;
}
我们入队列选用的是尾插。
4.判断队列是否为空
_Bool QEempty(QE* qe)
{assert(qe);return qe->size == 0;
}
5.出队
void QEPop(QE* qe)
{assert(qe);assert(!QEempty(qe));if (qe->size == 1){free(qe->head);qe->head = NULL;qe->tail = NULL;}else{QEnode* prev = qe->head->next;free(qe->head);qe->head = prev;}qe->size--;
}
对于出队我们选用头删。
6.返回队头和队尾
QEnode* QETop(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->head;
}
QEnode* QEDown(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->tail;
}
这就是我们当时表示出来队头和队尾的方便之处。
7.查看队尾内容
QEtype ShowDown(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->tail->val;
}
8.查看队列数量
int QESize(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->size;
}
9.销毁队列
void QEDestory(QE* qe)
{assert(qe);qe->head = qe->tail = NULL;qe->size = 0;free(qe->head);free(qe->tail);}
三.队列实现所有代码
QE.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QEtype;typedef struct QEnode{QEtype val;struct QEnode *next;
}QEnode;typedef struct QE
{QEnode* head;QEnode* tail;int size;
}QE;void QEInit(QE* qe);
void QEPush(QE* qe, QEtype x);
void QEPop(QE* qe);
_Bool QEempty(QE* qe);
QEnode* QETop(QE* qe);
QEnode* QEDown(QE* qe);
QEtype ShowDown(QE* qe);
int QESize(QE* qe);
void QEDestory(QE* qe);QE.c
void QEInit(QE* qe)
{assert(qe);qe->head = NULL;qe->tail = NULL;qe->size = 0;
}
void QEPush(QE* qe, QEtype x)
{assert(qe);QEnode* newnext = (QEnode*)malloc(sizeof(QEnode));if (newnext == NULL){perror(malloc);return;}newnext->next = NULL;newnext->val = x;if (qe->size == 0){qe->head = qe->tail = newnext;}else{qe->tail->next = newnext;qe->tail = newnext;}qe->size++;
}
_Bool QEempty(QE* qe)
{assert(qe);return qe->size == 0;
}
void QEPop(QE* qe)
{assert(qe);assert(!QEempty(qe));if (qe->size == 1){free(qe->head);qe->head = NULL;qe->tail = NULL;}else{QEnode* prev = qe->head->next;free(qe->head);qe->head = prev;}qe->size--;
}
QEnode* QETop(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->head;
}
QEnode* QEDown(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->tail;
}
QEtype ShowDown(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->tail->val;
}
int QESize(QE* qe)
{assert(qe);assert(!QEempty(qe));return qe->size;
}
void QEDestory(QE* qe)
{assert(qe);qe->head = qe->tail = NULL;qe->size = 0;free(qe->head);free(qe->tail);}test.c#include"QE.h"void test()
{QE qe = {0};QEInit(&qe);QEPush(&qe, 1);QEPush(&qe, 2);QEPush(&qe, 3);QEPush(&qe, 4);printf("队列数量%d\n", QESize(&qe));while (!QEempty(&qe)){QEnode* ret = QETop(&qe);printf("%d ", ret->val);QEPop(&qe);}printf("\n队列数量%d", QESize(&qe));}
int main()
{test();return 0;
}
四.结言
好了我么队列和栈就以及全部说完了,感谢大家的关注。
有喜欢的兄弟们可以一键三连!!
谢谢大家了,拜拜。