队列的链式存储
链式存储的结构
1、链式存储的结构
typedef int ElemType;
//链式队列结点的结构
typedef struct LinkNode {
ElemType data;
struct LinkNode* next;
}LinkNode;
//链式队列的结构
typedef struct {
LinkNode* front;
LinkNode* rear;
}LinkQueue;
2、单链表的结构对比
//单链表的结构
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode* next;//指向下一个结点
}LNode, * LinkList;
两种初始化方式
1、带头结点的初始化
//初始化(带头结点)
void InitQueue(LinkQueue& Q) {
//初始时 front、rear都指向头结点
Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
Q.front->next = NULL;
}
//带头结点的判空
bool IsEmpty(LinkQueue Q) {
if (Q.front == Q.rear)
return true;
else
return false;
}
2、不带头结点的初始化
/初始化(不带头结点)
void InitQueue(LinkQueue& Q) {
//初始时 front、rear都指向NULL
Q.front = NULL;
Q.rear = NULL;
}
//不带头结点的判空
bool IsEmpty2(LinkQueue Q) {
if (Q.front == NULL)
return true;
else
return false;
}
两种入队方式
1、带头结点的入队
//入队(带头结点)
void EnQueue(LinkQueue& Q, ElemType x) {
LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode)); //创建新结点
s->data = x;
s->next = NULL;
Q.rear->next = s; //新元素从队尾进入队列,因此将新结点插入到rear之后
Q.rear = s; //修改队尾指针,使队尾指针指向新元素
}
2、不带头结点的入队
//入队(不带头结点)
void EnQueue2(LinkQueue& Q, ElemType x) {
LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
s->data = x;
s->next = NULL;
if (Q.front == NULL) { //如果是空队列的情况,则插入的元素作为队列的第一个元素
Q.front = s; //修改队头队尾指针
Q.rear = s;
}
else { //新结点插入到rear结点之后
Q.rear->next = s;
Q.rear = s;
}
}
两种出队方式
1、带头结点的出队
//出队(带头结点)
bool DeQueue(LinkQueue& Q, ElemType x) {
if (Q.front == Q.rear)
return false; //空队
LinkNode* p = Q.front->next; //使p指向第一个结点,即要出队的结点
x = p->data; //用变量x返回队头元素
Q.front->next = p->next;//修改头结点的next指针
if (Q.rear == p) //如果该出队元素是队列中最后一个元素,则将队列置为空队列
Q.rear = Q.front;
free(p); //释放结点空间
return true;
}
//Q.front是头结点(第0个结点),Q.front->next是第一个结点,即要出队的结点
2、不带头结点的出队
//出队(不带头结点)
bool DeQueue2(LinkQueue& Q, ElemType x) {
if (Q.front == Q.rear)
return false; //空队
LinkNode* p = Q.front; //p指向队头结点,即要出队的结点
x = p->data;
Q.front = p->next;
if (Q.rear == p)
Q.rear = NULL;
Q.front = NULL;
free(p);
return true;
}
//没有头结点的情况下,Q.front即为队头结点,即要出队结点