队列的链式存储表示
队列的链式存储结构简称链队列,它是限制仅在表头进行删除操作和表尾进行插入操作的单链表。
需要两类不同的结点:数据元素结点,队列的队首指针和队尾指针的结点。
数据元素结点类型定义
typedef struct Qnode {
ElemType data;
struct Qnode* next;
}QNode;
指针结点类型定义
typedef struct link_queue {
QNode* front, * rear;
}Link_Queue;
链队列初始化
Link_Queue* Init_LinkQueue(void) {
Link_Queue* Q; QNode* p;
p = (QNode*)malloc(sizeof(QNode)); /* 开辟头结点 */
p->next = NULL;
Q = (Link_Queue*)malloc(sizeof(Link_Queue));
/* 开辟链队的指针结点 */
Q->front = Q->rear = p;
return(Q);
}
链队列的入队操作
Status Insert_CirQueue(Link_Queue* Q, ElemType e) {
/* 将数据元素e插入到链队列Q的队尾 */
QNode* New_node;
New_node = (QNode*)malloc(sizeof(QNode));
if (!New_node) return ERROR; /* 申请新结点失败,返回错误标志 */
New_node->data = e; /* 新结点数据域赋值 */
New_node->next = NULL; /* 形成新结点 */
Q->rear->next = New_node; Q->rear = New_node; /* 新结点插入到队尾 */
return OK;
}
链队列的出队操作
Status Delete_LinkQueue(Link_Queue* Q, ElemType* x) {
/* 将头结点删除,并将该结点的值赋值给 *x */
QNode* del_p;
if (Q->front == Q->rear) return ERROR; /* 队空 */
del_p = Q->front->next; /* 取队首结点 */
(*x) = del_p->data;
Q->front->next = del_p->next; /* 修改队首指针 */
if (del_p == Q->rear) Q->rear = Q->front;
/* 当队列只有一个结点时应防止丢失队尾指针 */
free(del_p);
return OK;
}
链队列的头结点元素提取
Status Get_LinkQueue(Link_Queue* Q, ElemType* x) {
/* 将头结点直接该结点的值赋值给 *x */
if (Q->front == Q->rear) return ERROR;
(*x) = Q->front->next->data;
return OK;
}
链队列的撤销
Status Free_LinkQueue(Link_Queue* Q) {
//QNode* delete_node;
//if (Q->front == Q->rear) return ERROR;
//while (Q->front->next != NULL) {
// printf("\nhello");
// QNode* delete_node = Q->front->next;
// printf("%d", delete_node->data);
// Q->front->next = delete_node->next;
// free(delete_node);
//}
//return OK;
while (Q->front!=NULL) {
Q->rear = Q->front->next; /* 令尾指针指向队列的第一个结点 */
free(Q->front); /* 每次释放一个节点 */
/* 第一次是头结点,以后是元素结点 */
Q->front = Q->rear;
}
return OK;
}
打印链队列中元素
Status Printf_LinkQueue(Link_Queue* Q) {
QNode* print_node;
if (Q->front == Q->rear) return ERROR; /* 队空 */
print_node = Q->front; /* 取队首结点 */
while (print_node!= Q->rear) {
print_node = print_node->next;
printf("%d ", print_node->data);
}
return OK;
}
全部代码
#define _CRT_SECURE_NO_WARNINGS
#include "queue.h"
#include <stdlib.h>
#include<stdio.h>
#define ERROR 0
#define OK 1
typedef int ElemType;
typedef int Status;
typedef struct Qnode {
ElemType data;
struct Qnode* next;
}QNode;
typedef struct link_queue {
QNode* front, * rear;
}Link_Queue;
Link_Queue* Init_LinkQueue(void) {
Link_Queue* Q; QNode* p;
p = (QNode*)malloc(sizeof(QNode)); /* 开辟头结点 */
p->next = NULL;
Q = (Link_Queue*)malloc(sizeof(Link_Queue));
/* 开辟链队的指针结点 */
Q->front = Q->rear = p;
return(Q);
}
Status Insert_CirQueue(Link_Queue* Q, ElemType e) {
/* 将数据元素e插入到链队列Q的队尾 */
QNode* New_node;
New_node = (QNode*)malloc(sizeof(QNode));
if (!New_node) return ERROR; /* 申请新结点失败,返回错误标志 */
New_node->data = e; /* 新结点数据域赋值 */
New_node->next = NULL; /* 形成新结点 */
Q->rear->next = New_node; Q->rear = New_node; /* 新结点插入到队尾 */
return OK;
}
Status Delete_LinkQueue(Link_Queue* Q, ElemType* x) {
/* 将头结点删除,并将该结点的值赋值给 *x */
QNode* del_p;
if (Q->front == Q->rear) return ERROR; /* 队空 */
del_p = Q->front->next; /* 取队首结点 */
(*x) = del_p->data;
Q->front->next = del_p->next; /* 修改队首指针 */
if (del_p == Q->rear) Q->rear = Q->front;
/* 当队列只有一个结点时应防止丢失队尾指针 */
free(del_p);
return OK;
}
Status Printf_LinkQueue(Link_Queue* Q) {
QNode* print_node;
if (Q->front == Q->rear) return ERROR; /* 队空 */
print_node = Q->front; /* 取队首结点 */
while (print_node!= Q->rear) {
print_node = print_node->next;
printf("%d ", print_node->data);
}
return OK;
}
Status Free_LinkQueue(Link_Queue* Q) {
//QNode* delete_node;
//if (Q->front == Q->rear) return ERROR;
//while (Q->front->next != NULL) {
// printf("\nhello");
// QNode* delete_node = Q->front->next;
// printf("%d", delete_node->data);
// Q->front->next = delete_node->next;
// free(delete_node);
//}
//return OK;
while (Q->front!=NULL) {
Q->rear = Q->front->next; /* 令尾指针指向队列的第一个结点 */
free(Q->front); /* 每次释放一个节点 */
/* 第一次是头结点,以后是元素结点 */
Q->front = Q->rear;
}
return OK;
}
Status Get_LinkQueue(Link_Queue* Q, ElemType* x) {
/* 将头结点直接该结点的值赋值给 *x */
if (Q->front == Q->rear) return ERROR;
(*x) = Q->front->next->data;
return OK;
}
int main(void) {
Link_Queue* link;
int elem;
link=Init_LinkQueue();
/* 插入1 2 3 4 5 6 7 8 */
Insert_CirQueue(link, 1);
Insert_CirQueue(link, 2);
Insert_CirQueue(link, 3);
Insert_CirQueue(link, 4);
Insert_CirQueue(link, 5);
Insert_CirQueue(link, 6);
Insert_CirQueue(link, 7);
Insert_CirQueue(link, 8);
Printf_LinkQueue(link); /* 打印队link */
Delete_LinkQueue(link, &elem);
Delete_LinkQueue(link, &elem);
Delete_LinkQueue(link, &elem);
Delete_LinkQueue(link, &elem); /* 删除四次队 link */
printf("\n");
Printf_LinkQueue(link); /* 打印队 */
Get_LinkQueue(link, &elem);
printf("\nelem: %d", elem);
Free_LinkQueue(link);
}
队列的顺序存储结构–循环队列
为充分利用向量空间,克服“假溢出”现象的方法是:将为队列分配的向量空间看成为一个首尾相接的圆环,并将这种队列成为循环队列(Circular Queue)。
结点类型定义
typedef struct seqqueue {
int element[MAXSIZE]; /* 队列的元素空间 */
int front; /* 头指针指示器 */
int rear; /* 尾指针指示器 */
}SeqQueue;
循环队列的初始化
void InitSeqQueue(SeqQueue* Q) {
/* 将*Q初始化为一个空的循环队列 */
Q->front = Q->rear = 0;
}
入队操作
Status EnterSeqQueue(SeqQueue* Q, int x) {
/* 将元素x入队 */
if ((Q->rear + 1) % MAXSIZE == Q->front) /* 队列已满 */
return ERROR;
Q->element[Q->rear] = x;
Q->rear = (Q->rear + 1) % MAXSIZE; /* 重新设置队尾指针 */
return OK;
}
出队操作
Status DeleteSeqQueue(SeqQueue* Q, int* x) {
if (Q->front == Q->rear) /* 队列为空 */
return ERROR;
(*x) = Q->element[Q->front];
Q->front = (Q->front + 1) % MAXSIZE; /* 重新设置队头指针 */
return OK; /* 操作成功 */
}
循环队列打印
void PrintfSeqQueue(SeqQueue S) {
while (S.front != S.rear) {
printf("%d ", S.element[S.front]);
S.front = (S.front + 1) % MAXSIZE;
}
}
循环队列全部代码
#include <stdlib.h>
#include<stdio.h>
#define ERROR 0
#define OK 1
#define MAXSIZE 50 /*队列的最大长度*/
typedef int ElemType;
typedef int Status;
typedef struct seqqueue {
int element[MAXSIZE]; /* 队列的元素空间 */
int front; /* 头指针指示器 */
int rear; /* 尾指针指示器 */
}SeqQueue;
void InitSeqQueue(SeqQueue* Q) {
/* 将*Q初始化为一个空的循环队列 */
Q->front = Q->rear = 0;
}
Status EnterSeqQueue(SeqQueue* Q, int x) {
/* 将元素x入队 */
if ((Q->rear + 1) % MAXSIZE == Q->front) /* 队列已满 */
return ERROR;
Q->element[Q->rear] = x;
Q->rear = (Q->rear + 1) % MAXSIZE; /* 重新设置队尾指针 */
return OK;
}
Status DeleteSeqQueue(SeqQueue* Q, int* x) {
if (Q->front == Q->rear) /* 队列为空 */
return ERROR;
(*x) = Q->element[Q->front];
Q->front = (Q->front + 1) % MAXSIZE; /* 重新设置队头指针 */
return OK; /* 操作成功 */
}
void PrintfSeqQueue(SeqQueue S) {
while (S.front != S.rear) {
printf("%d ", S.element[S.front]);
S.front = (S.front + 1) % MAXSIZE;
}
}
int main(void) {
SeqQueue queue;
int elem;
InitSeqQueue(&queue);
EnterSeqQueue(&queue, 1);
EnterSeqQueue(&queue, 2);
EnterSeqQueue(&queue, 3);
EnterSeqQueue(&queue, 4);
PrintfSeqQueue(queue);
DeleteSeqQueue(&queue, &elem);
PrintfSeqQueue(queue);
}