链式队列的过程分析与实现
一、队列的组成
概念部分:链式队列是一个先进先出的由链表指针链接的动态内存。队列的实现有两种:基于数组的队列和机遇链表的队列,但是要注意的是基于数组的队列必须是循环队列才可以,因为要节省内存。链式队列的组成由两部分组成的:结点(node)和指针(rear front),这两部分都是需要建立结构体实现的。
二、操作实现部分
1、结构体的建立:
结点部分的结构体建立:
typedef struct node{
int data;
struct node *pNext;
}NODE,*PNODE;
指针部分的结构体建立:
typedef struct queue{
PNODE Rear;//这是尾队列
PNODE Front;//这是头队列
}QUEUE,*PQUEUE;
2、队列的初始化:
队列需要有一个空的结点方便我们的操作,所以队列的初始化就是建立空队列的过程
注意:队列中是头出尾进
void initQueue(PQUEUE pQ){
PNODE pNew;
pNew=(PNODE)malloc(sizeof(NODE));
pNew->pNext=NULL;
pQ->Rear=pNew;
pQ->Front=pQ->Rear;
}//这样我们就建好了一个空的队列
3、队列的入队操作:
步骤分析:1、将Rear->pNext指向新产生的结点
2、调整指针Rear指向新的结点
3、将新结点的指针域置为空
void pushQueue(PQUEUE pQ){
PNODE pNew;
int val;
printf("please enter the data:");
scanf("%d",&val);
pNew=(PNODE)malloc(sizeof(NODE));
pQ->Rear->pNext=pNew;
pQ->Rear=pNew;
pQ->Rear->pNext=NULL;//将指针域置为空
pQ->Rear->data=val;
}
4、队列的出队操作:
步骤分析:1、先将头指针Front指向的下一个结点的地址存储
2、将Front指针移动,使其指向出队结点的下一个结点
3、利用我们存储的地址将内存释放
void popQueue(PQUEUE pQ){
PNODE pN;
pN=pQ->Front->pNext;
pQ->Front->pNext=pQ->Front->pNext->pNext;
free(pN);
printf("Node remove queue succeeded\n");
}
5、队列是否为空:
过程分析:只需要判断rear指针和front指针是不是指向同一个位置就可以了
void emptyQueue(PQUEUE pQ){
if(pQ->Rear==pQ->Front){
printf("The queue is empty\n");
}else{
printf("The queue isn`t empty\n");
}
}//也可以根据需要将void 设置为自己需要的返回值
6、查看队列的队头元素:
过程分析:直接通过rear指针获取首元素
void frontElement(PQUEUE pQ){
printf("The first element of the queue is %d",pQ->Front->data);
}//可以根据自己的需求设置相应的返回值
7、查看队列的队尾元素:
过程分析:直接通过rear指针获取尾元素
void rearElement(PQUEUE pQ){
printf("The last element of the queue is %d",pQ->Rear->pNext->data);
}//可以根据自己的需求设置相应的返回值
8、遍历队列:
过程分析:利用循环和front指针完成遍历
void traversalQueue(PQUEUE pQ){
PNODE pN=pQ->Front;
while(pN->pNext){
printf("%d\n",pN->pNext->data);
pN=pN->pNext;
}
}
下面是可以直接运行的代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct node {
int data;
struct node *pNext;
} NODE,*PNODE;
typedef struct queue {
PNODE Rear;
PNODE Front;
} QUEUE,*PQUEUE;
void initQueue(PQUEUE pQ) {
PNODE pNew;
pNew=(PNODE)malloc(sizeof(NODE));
pNew->pNext=NULL;
pQ->Rear=pNew;
pQ->Front=pQ->Rear;
}//这样我们就建好了一个空的队列
void pushQueue(PQUEUE pQ) {
PNODE pNew;
int val;
printf("please enter the data:");
scanf("%d",&val);
pNew=(PNODE)malloc(sizeof(NODE));
pQ->Rear->pNext=pNew;
pQ->Rear=pNew;
pQ->Rear->pNext=NULL;//将指针域置为空
pQ->Rear->data=val;
}
void popQueue(PQUEUE pQ) {
PNODE pN;
pN=pQ->Front->pNext;
pQ->Front->pNext=pQ->Front->pNext->pNext;
free(pN);
printf("Node remove queue succeeded\n");
}
void emptyQueue(PQUEUE pQ) {
if((pQ->Rear)==(pQ->Front)) {
printf("The queue is empty\n");
} else {
printf("The queue isn`t empty\n");
}
}//也可以根据需要将void 设置为自己需要的返回值
void rearElement(PQUEUE pQ) {
int val=pQ->Rear->data;
printf("The last element of the queue is %d\n",val);
}//可以根据自己的需求设置相应的返回值
void frontElement(PQUEUE pQ) {
int val=pQ->Front->pNext->data;
printf("The first element of the queue is %d\n",val);
}//可以根据自己的需求设置相应的返回值
void traversalQueue(PQUEUE pQ) {
PNODE pN=pQ->Front;
while(pN->pNext) {
printf("%d\n",pN->pNext->data);
pN=pN->pNext;
}
}
int main() {
//implementing a circular queue through an array
QUEUE Q;
initQueue(&Q);
pushQueue(&Q);
pushQueue(&Q);
pushQueue(&Q);
pushQueue(&Q);
popQueue(&Q);
traversalQueue(&Q);
rearElement(&Q);
frontElement(&Q);
emptyQueue(&Q);
return 0;
}
下面是运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/eb917a620880c159b036677f3aea1ecb.png)