Files
2020-12-01 22:02:43 +08:00

339 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 队列
## 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;
}
```