【数据结构-队列】队列的基本操作
目录
1 顺序表实现队列(循环队列)
实现方式:
- 队尾指针指向队尾元素
- 队尾指针指向队尾元素的下一位置(队头指针在队尾指针的下一个位置作为队满标志)
1.1 定义
- 队尾指针指向队尾元素:
# define MAX 50 // 队列的容量
typedef struct Queue{
int data[MAX];
int size; // 增设记录队列当前元素的个数
int front, rear;
} Queue;
- 队尾指针指向队尾元素的下一位置:
# define MAX 50 // 队列的容量
typedef struct Queue{
int data[MAX];
int front, rear;
} Queue;
1.2 初始化
- 队尾指针指向队尾元素:
void InitQueue (Queue &Q){
Q.front = 0;
Q.rear = MAX-1;
Q.size = 0;
}
- 队尾指针指向队尾元素的下一位置:
void InitQueue (Queue &Q){
Q.front = 0;
Q.rear = 0;
}
1.3 判队空
- 队尾指针指向队尾元素:
bool EmptyQueue (Queue &Q){
if (Q.size == 0)
return true;
else
return false;
}
- 队尾指针指向队尾元素的下一位置:
bool EmptyQueue (Queue &Q){
if (Q.front == Q.rear)
return true;
else
return false;
}
1.4 判队满
- 队尾指针指向队尾元素:
bool FullQueue (Queue &Q){
if (Q.size == MAX)
return true;
else
return false;
}
- 队尾指针指向队尾元素的下一位置:
bool FullQueue (Queue &Q){
if ((Q.rear+1) % MAX == Q.front)
return true;
else
return false;
}
1.5 出队
- 队尾指针指向队尾元素:
bool DeQueue (Queue &Q, int &x){
if (Q.size == 0)
return false;
x = Q.data[Q.front]; // 获得出队元素
Q.front = (Q.front+1) % MAX; // 队头指针加 1
return true;
}
- 队尾指针指向队尾元素的下一位置:
bool DeQueue (Queue &Q, int &x){
if (Q.front == Q.rear)
return false;
x = Q.data[Q.front]; // 获得出队元素
Q.front = (Q.front+1) % MAX; // 队头指针加 1
return true;
}
1.6 入队
- 队尾指针指向队尾元素:
bool EnQueue (Queue &Q, const int x){
if (Q.size == MAX)
return false;
Q.rear = (Q.rear+1) % MAX; // 队尾指针加 1
Q.data[Q.rear] = x; // 入队
return true;
}
- 队尾指针指向队尾元素的下一位置:
bool EnQueue (Queue &Q, const int x){
if ((Q.rear+1) % MAX == Q.front)
return false;
Q.data[Q.rear] = x; // 入队
Q.rear = (Q.rear+1) % MAX; // 队尾指针指向下一个位置
return true;
}
1.7 队长
int LenQueue (Queue &Q){
return (Q.rear - Q.front + MAX) % MAX;
}
2 单向链表实现队列
单向链表实现队列:链表头出队,链表尾入队。
实现方式:
- 不带头结点
- 带头结点(头结点可存储当前队列的元素个数)
2.1 定义
- 不带头结点:
#define MAX 50 // 队列的容量
typedef struct LinkNode{
int data;
struct LinkNode *next;
}LinkNode;
typedef struct Queue{
int size; // 增设记录队列当前元素的个数
struct LinkNode *front;
struct LinkNode *rear;
}LinkQueue;
- 带头结点:
#define MAX 50 // 队列的容量
typedef struct LinkNode{
int data;
struct LinkNode *next;
}LinkNode;
typedef struct Queue{
// struct LinkNode *front; // 队头指针可由头结点指针充当实现
struct LinkNode *rear;
struct LinkNode *head; // 头结点指针
}LinkQueue;
2.2 初始化
- 不带头结点:
void InitQueue (LinkQueue &Q){
Q.front = NULL;
Q.rear = NULL;
Q.size = 0;
}
- 带头结点:
void InitQueue (LinkQueue &Q){
Q.head = (LinkNode *) malloc(sizeof(LinkNode)); // 创建头结点
Q.rear = Q.head; // 初始时,队头指针和队尾指针指向头结点
Q.head->data = 0; // 记录队列当前元素个数
Q.head->next = NULL;
}
2.3 判队空
- 不带头结点:
bool EmptyQueue (LinkQueue &Q){
if ((Q.front == NULL) || (Q.rear == NULL))
return true;
else
return false;
}
或
bool EmptyQueue (LinkQueue &Q){
if (Q.size == 0)
return true;
else
return false;
}
- 带头结点:
bool EmptyQueue (LinkQueue &Q){
if (Q.head->data == 0)
return true;
else
return false;
}
或
bool EmptyQueue (LinkQueue &Q){
if (Q.head == Q.rear)
return true;
else
return false;
}
2.4 判队满
- 不带头结点:
bool FullQueue (LinkQueue &Q){
if (Q.size == MAX)
return true;
else
return false;
}
- 带头结点:
bool FullQueue (LinkQueue &Q){
if (Q.head->data == MAX)
return true;
else
return false;
}
2.5 出队
- 不带头结点:
bool DeQueue (LinkQueue &Q, int &x){
LinkNode *frontNext; // 记录队头指针的下一个结点
if ((Q.front == NULL) || (Q.rear == NULL)) // 判空,或:Q.size == 0
return false;
x = Q.front->data;
if (Q.front == Q.rear){ // 若队列只有一个结点
free(Q.front);
Q.front = NULL;
Q.rear = NULL;
}
else{
frontNext = Q.front->next; // 记录队头指针的下一个结点
free(Q.front);
Q.front = frontNext; // 更新队头指针
}
Q.size--; // 出队,减少一个元素
return true;
}
- 带头结点:
bool DeQueue (LinkQueue &Q, int &x){
LinkNode *front = Q.head->next; // 队头指针
if (Q.head == Q.rear) // 判空,或:Q.head->data == 0
return false;
x = front->data;
Q.head->data--; // 出队,减少一个元素
Q.head->next = front->next; // 头结点的指针域指向队头结点的下一个结点
if (front == Q.rear) // 若队列只有一个结点,出队后只剩头结点
Q.rear = Q.head; // 队尾指针指向头结点
free(front);
return true;
}
2.6 入队
- 不带头结点:
bool EnQueue (LinkQueue &Q, const int x){
LinkNode *newNode;
if (Q.size == NUM) // 判满
return false;
newNode = (LinkNode *) malloc(sizeof(LinkNode));
newNode->data = x;
newNode->next = NULL;
if ((Q.front == NULL) || (Q.rear == NULL)){ // 如果队列为空 // 或:Q.size == 0
Q.front = newNode;
Q.rear = newNode;
}
else{
Q.rear->next = newNode; // 队尾指针的指针域指向新结点
Q.rear = newNode; // 队尾指针指向新结点
}
Q.size++; // 入队,增加一个元素
return true;
}
- 带头结点:
bool EnQueue (LinkQueue &Q, const int x){
LinkNode *newNode;
if (Q.head->data == NUM) // 判满
return false;
newNode = (LinkNode *) malloc(sizeof(LinkNode));
newNode->data = x;
newNode->next = NULL;
Q.head->data++; // 入队,增加一个元素
Q.rear->next = newNode; // 队尾指针的指针域指向新结点
Q.rear = newNode; // 队尾指针指向新结点
return true;
}