链队列:头进尾出的单链表
队头指针:指向链队列的头结点
队尾指针:指向终端节点
空队列:front 和 rear 都指向头结点
#include <iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
#include "math.h"
#include "io.h"
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status;
typedef int QElemType;
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
Status InitQueue(LinkQueue * Q){
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
if(!Q->front)
exit(OVERFLOW);
Q->front->next = NULL;
}
Status EnQueue(LinkQueue * Q ,QElemType e){ //链式存储和顺序存储不同连接时需要指向上一个节点
QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
if(!s)
exit(OVERFLOW);
s->data = e;
s->next = NULL;
Q->rear->next = s; //连接节点
Q->rear = s; //设置队尾节点
}
Status DeQueue(LinkQueue *Q , QElemType *e){ //别忘了还有头结点 front不变永远指向头结点
//队头永远是头结点的下一个
if(Q->front == Q->rear) //如果队列为空
return ERROR;
QueuePtr q = Q->front->next;
*e = q->data;
Q->front->next = q->next; //指向新的队头
if(q == Q->rear){ //如果删除的是队尾(即只有一个元素),删除后将队尾指向头结点
Q->rear = Q->front;
}
free(q);
return OK;
}
int ListLength(LinkQueue Q){
if(Q.front == Q.rear){
return 0;
}
int length = 0;
QueuePtr ptr = Q.front->next; //Q.front表示头结点,Q.front->next指向队头
while(ptr){
length++;
ptr = ptr->next;
}
return length;
}
Status getHeadElement(LinkQueue Q , QElemType *e){
if(Q.front->next == NULL){ //也是判断链表为空的方式。
return ERROR;
}
*e = Q.front->next->data;
return OK;
}
Status ClearQueue(LinkQueue * Q){
if(Q->rear == Q->front){ //都指向头结点
return ERROR;
}
QueuePtr ptr = Q->front->next;
while(ptr){
QueuePtr remember = ptr->next;
printf("%d\n",ptr->data);
free(ptr);
ptr = remember;
}
Q->front->next=NULL;//头结点的下一个为空
Q->rear = Q->front;
return OK;
}
Status DesQueue(LinkQueue *Q){
while(Q->front){
QueuePtr ptr = Q->front->next;
free(Q->front); //从头结点开始销毁
Q->front = ptr;
}
}
int main()
{
LinkQueue q ;
InitQueue(&q); //设置初始化
for(int i=0;i<10;i++){
EnQueue(&q,i+1+2);
}
QueuePtr ptr = q.front->next;
printf("进入的队列的顺序为\n");
while(ptr){
printf("%d\n",ptr->data);
ptr = ptr->next;
}
printf("队列的长度是%d\n",ListLength(q));
ptr = q.front->next;
int value;
printf("元素出队的顺序为\n");
while(q.front != q.rear){
DeQueue(&q,&value);
printf("%d\n",value);
// printf("%d\n",DeQueue(&q,&value));
// printf("%d\n",value);
}
printf("测试清空队列的元素\n");
for(int i=0;i<10;i++){
EnQueue(&q,i+1+2);
}
ptr = q.front->next;
while(ptr){
printf("%d\n",ptr->data);
ptr = ptr->next;
}
ClearQueue(&q);
return 0;
}
在可以确定队列长度的情况下,建议使用循环队列,如果无法预估队列的长度,建议使用链队列