文章目录
- [1. 队列](#1. 队列)
-
- [1.1 什么是队列](#1.1 什么是队列)
- [1.2 队列的结构](#1.2 队列的结构)
- [1.3 队列初始化](#1.3 队列初始化)
- [1.4 队列入栈](#1.4 队列入栈)
- [1.5 出队列](#1.5 出队列)
- [1.6 查找队列有效元素个数](#1.6 查找队列有效元素个数)
- [1.7 取队头和队尾数据](#1.7 取队头和队尾数据)
- [1.8 销毁链表](#1.8 销毁链表)
- [2. 用两个队列实现栈](#2. 用两个队列实现栈)
- [3. 用两个栈实现队列](#3. 用两个栈实现队列)
- [4. 循环队列](#4. 循环队列)
1. 队列
- 注:文中Queue是队列,Quene是错误写法
1.1 什么是队列
- 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表
- 栈只允许在栈顶进行插入数据删除数据的操作,称为入栈、出栈(或压栈)
- 队列则是队尾进队头出,满足先进先出的原则,而栈则是后进先出
1.2 队列的结构
c
typedef int QueueDataType;
//定义队列节点的结构
typedef struct QueueNode
{
QueueDataType data;
struct QueueNode* next;
}QueueNode;
//定义队列的结构
typedef struct Queue
{
QueueNode* phead;//队头
QueueNode* ptail;//队尾
}Queue;
1.3 队列初始化
1.4 队列入栈
c
//入队列
void QueuePush(Queue* pq, QueueDataType x)
{
assert(pq);
//申请节点
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode== NULL)
{
perror("malloc fail!\n");
exit(1);
}
newnode->data = x;
newnode->next = NULL;
//队列为空,队头队尾都是newnode
if (pq->phead == NULL)
{
pq->phead = pq->ptail = newnode;
}
//队列不为空
else
{
pq->ptail->next = newnode;
//pq->ptail往后走
pq->ptail = pq->ptail->next;
}
}
1.5 出队列
c
//队列判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
//出队列--头删
void QueuePop(Quene* pq)
{
assert(pq && !QueueEmpty(pq));
//队列只有一个有效数据
if (pq->phead == pq->ptail)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
//队列有多个有效数据
else
{
QueueNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
}
1.6 查找队列有效元素个数
c
//查找队列有效元素个数
int QueueSize(Queue* pq)
{
assert(pq);
//第一种
//int size = 0;
//QueueNode* pcur = pq->phead;
//while (pcur)
//{
// size++;
// pcur = pcur->next;
//}
//return size;
//第二种
return pq->size;
}
1.7 取队头和队尾数据
1.8 销毁链表
2. 用两个队列实现栈
- 栈的结构
- 栈的初始化
- 入栈
- 出栈----取栈顶元素
- 返回栈顶元素
- 判断栈是否为空和销毁栈
3. 用两个栈实现队列
- 自定义的队列的数据结构
- 队列的初始化
- 入队和出队
- 判断队列是否为空和销毁队列
4. 循环队列
- 循环队列初始化
- 判断循环队列是否为空和循环队列是否满了
- 循环队列插入元素
- 循环队列出队列
- 循环队列取队头和队尾
- 释放循环队列