mirror of
https://github.com/happyflyer/wangdao-data-structure.git
synced 2026-02-02 18:20:02 +08:00
339 lines
4.8 KiB
Markdown
339 lines
4.8 KiB
Markdown
# 队列
|
||
|
||
## 1. 队列的顺序实现
|
||
|
||
### 1.1. 定义
|
||
|
||
用顺序存储方式实现的队列。
|
||
|
||
```cpp
|
||
#define MaxSize 10
|
||
typedef struct
|
||
{
|
||
ElemType data[MaxSize];
|
||
int front, rear; // 队头、队尾指针
|
||
} SqQueue;
|
||
```
|
||
|
||
$MaxSize*sizeof(ElemType)+8B$
|
||
|
||
### 1.2. 初始化队列
|
||
|
||
```cpp
|
||
// 初始化队列
|
||
void InitQueue(SqQueue &Q)
|
||
{
|
||
Q.front = Q.rear = 0;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 判断队列是否为空
|
||
bool QueueEmpty(SqQueue Q)
|
||
{
|
||
return Q.rear == Q.front;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 判断队列是否已满
|
||
bool QueueFull(SqQueue Q)
|
||
{
|
||
return (Q.rear + 1) % MaxSize == Q.front;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 获取队长
|
||
int Length(SqQueue Q)
|
||
{
|
||
return (Q.rear + MaxSize - Q.front) % MaxSize;
|
||
}
|
||
```
|
||
|
||
### 1.3. 入队
|
||
|
||
队尾指针指向队尾元素的下一个位置。
|
||
|
||
```cpp
|
||
// 入队
|
||
bool EnQueue(SqQueue &Q, int x)
|
||
{
|
||
if (QueueFull(Q))
|
||
{
|
||
return false;
|
||
}
|
||
Q.data[Q.rear] = x;
|
||
Q.rear = (Q.rear + 1) % MaxSize;
|
||
return true;
|
||
}
|
||
```
|
||
|
||
### 1.4. 出队
|
||
|
||
```cpp
|
||
// 出队
|
||
bool DeQueue(SqQueue &Q, int x)
|
||
{
|
||
if (QueueEmpty(Q))
|
||
{
|
||
return false;
|
||
}
|
||
x = Q.data[Q.front];
|
||
Q.front = (Q.front + 1) % MaxSize;
|
||
return true;
|
||
}
|
||
```
|
||
|
||
### 1.5. 获取队头元素
|
||
|
||
```cpp
|
||
// 读取队头元素
|
||
bool GetHead(SqQueue &Q, int &x)
|
||
{
|
||
if (QueueEmpty(Q))
|
||
{
|
||
return false;
|
||
}
|
||
x = Q.data[Q.front];
|
||
return true;
|
||
}
|
||
```
|
||
|
||
### 1.6. 不要浪费最后一个空位
|
||
|
||
加入辅助变量。
|
||
|
||
#### 1.6.1. size
|
||
|
||
```cpp
|
||
#define MaxSize 10
|
||
typedef struct
|
||
{
|
||
ElemType data[MaxSize];
|
||
int front, rear;
|
||
int size;
|
||
} SqQueue;
|
||
```
|
||
|
||
- 初始时:`Q.front = Q.rear = 0;`,`Q.size = 0;`
|
||
- 入队:`Q.size++;`
|
||
- 出队:`Q.size--;`
|
||
- 队满条件:`Q.size == MaxSize;`
|
||
- 队空条件:`Q.size == 0;`
|
||
|
||
#### 1.6.2. tag
|
||
|
||
```cpp
|
||
#define MaxSize 10
|
||
typedef struct
|
||
{
|
||
ElemType data[MaxSize];
|
||
int front, rear;
|
||
int tag;
|
||
} SqQueue;
|
||
```
|
||
|
||
- 初始时:`Q.front = Q.rear = 0;`,`Q.tag = 0;`
|
||
- 入队:`Q.tag = 1;`,只有入队操作,才能导致队满。
|
||
- 出队:`Q.tag = 0;`,只有出队操作,才能导致队空。
|
||
- 队满条件:`Q.front == Q.rear && Q.tag == 1;`
|
||
- 队空条件:`Q.front == Q.rear && Q.tag == 0;`
|
||
|
||
### 1.7. 队尾指针指向队尾元素
|
||
|
||
入队:
|
||
|
||
```cpp
|
||
Q.rear = (Q.rear + 1) % MaxSize;
|
||
Q.data[Q.rear] = x;
|
||
```
|
||
|
||
初始化:
|
||
|
||
```cpp
|
||
Q.front = 0;
|
||
Q.rear = MaxSize - 1;
|
||
```
|
||
|
||
判空:
|
||
|
||
```cpp
|
||
(Q.rear + 1) % MaxSize == Q.front;
|
||
```
|
||
|
||
判满(牺牲一个存储单元):
|
||
|
||
```cpp
|
||
(Q.rear + 2) % MaxSize == Q.front;
|
||
```
|
||
|
||
## 2. 队列的链式实现
|
||
|
||
### 2.1. 定义
|
||
|
||
```cpp
|
||
typedef struct LNode
|
||
{
|
||
ElemType data;
|
||
struct LNode *next;
|
||
} LNode;
|
||
typedef struct
|
||
{
|
||
LNode *front, *rear; // 队列的队头、队尾指针
|
||
} LinkQueue;
|
||
```
|
||
|
||
### 2.2. 初始化
|
||
|
||
```cpp
|
||
// 初始化队列
|
||
bool InitQueue(LinkQueue &Q)
|
||
{
|
||
LNode *s = (LNode *)malloc(sizeof(LNode));
|
||
if (s == NULL)
|
||
{
|
||
return false;
|
||
}
|
||
s->next = NULL;
|
||
Q.front = Q.rear = s;
|
||
return true;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 判断队列是否为空
|
||
bool QueueEmpty(LinkQueue Q)
|
||
{
|
||
return Q.rear == Q.front;
|
||
}
|
||
```
|
||
|
||
### 2.3. 入队
|
||
|
||
```cpp
|
||
// 入队
|
||
bool EnQueue(LinkQueue &Q, int x)
|
||
{
|
||
LNode *s = (LNode *)malloc(sizeof(LNode));
|
||
s->data = x;
|
||
s->next = NULL;
|
||
Q.rear->next = s;
|
||
Q.rear = s;
|
||
return true;
|
||
}
|
||
```
|
||
|
||
### 2.4. 出队
|
||
|
||
```cpp
|
||
// 出队
|
||
bool DeQueue(LinkQueue &Q, int x)
|
||
{
|
||
if (QueueEmpty(Q))
|
||
{
|
||
return false;
|
||
}
|
||
LNode *q = Q.front->next;
|
||
x = q->data;
|
||
Q.front->next = q->next;
|
||
if (Q.rear == q) // 如果是最后一个结点出队
|
||
{
|
||
Q.rear = Q.front;
|
||
}
|
||
free(q);
|
||
return true;
|
||
}
|
||
```
|
||
|
||
### 2.5. 获取队头元素
|
||
|
||
```cpp
|
||
// 读取队头元素
|
||
bool GetHead(LinkQueue &Q, int &x)
|
||
{
|
||
if (QueueEmpty(Q))
|
||
{
|
||
return false;
|
||
}
|
||
LNode *q = Q.front->next;
|
||
x = q->data;
|
||
return true;
|
||
}
|
||
```
|
||
|
||
### 2.6. 不带头结点
|
||
|
||
```cpp
|
||
// 初始化队列
|
||
bool InitQueue(LinkQueue &Q)
|
||
{
|
||
Q.front = Q.rear = NULL;
|
||
return true;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 判断队列是否为空
|
||
bool QueueEmpty(LinkQueue Q)
|
||
{
|
||
return Q.front = NULL;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 入队
|
||
bool EnQueue(LinkQueue &Q, int x)
|
||
{
|
||
LNode *s = (LNode *)malloc(sizeof(LNode));
|
||
s->data = x;
|
||
s->next = NULL;
|
||
if (Q.front == NULL)
|
||
{
|
||
Q.front = s;
|
||
Q.rear = s;
|
||
}
|
||
else
|
||
{
|
||
Q.rear->next = s;
|
||
Q.rear = s;
|
||
}
|
||
return true;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 出队
|
||
bool DeQueue(LinkQueue &Q, int x)
|
||
{
|
||
if (QueueEmpty(Q))
|
||
{
|
||
return false;
|
||
}
|
||
LNode *q = Q.front;
|
||
x = q->data;
|
||
Q.front = q->next;
|
||
if (Q.rear == q) // 如果是最后一个结点出队
|
||
{
|
||
Q.front = NULL;
|
||
Q.rear = NULL;
|
||
}
|
||
free(q);
|
||
return true;
|
||
}
|
||
```
|
||
|
||
```cpp
|
||
// 读取队头元素
|
||
bool GetHead(LinkQueue &Q, int &x)
|
||
{
|
||
if (QueueEmpty(Q))
|
||
{
|
||
return false;
|
||
}
|
||
LNode *q = Q.front;
|
||
x = q->data;
|
||
return true;
|
||
}
|
||
```
|