数据结构(十)---链式队列
#### linkqueue.h
#ifndef _LQUEUE_H
#define _LQUEUE_H
//引入相关库
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义元素数据类型的别名
typedef int DATA;
//定义链式队列的节点结构体
typedef struct node
{
DATA data; //节点数据
struct node *next; //后继指针
}NODE;
//定义链式队列的结构体
typedef struct
{
NODE *front; //队头指针
NODE *rear; //队尾指针
int size; //队列元素个数
}LinkQueue;
/**
* 队列初始化(初始属性的赋予)
* @return 成功返回结构体指针q,否则返回NULL
*/
extern LinkQueue *lqueue_init();
/**
* 判断队列是否为空
* @param q 待操作的队列
* @return 队列为空返回1,否则返回0
*/
extern int lqueue_isempty(LinkQueue *q);
/**
* 入队
* @param q 待操作的队列
* @param data 待插入的数据
* @return 成功返回0,否则返回-1
*/
extern int lqueue_enqueue(LinkQueue *q, DATA data);
/**
* 出队(维护队头指针)---释放队头节点,然后将下一个节点作为新的队头节点
* @param q 待操作的队列
* @param data 接收出队元素的指针
* @return 成功返回0,否则返回-1
*/
extern int lqueue_dequeue(LinkQueue *q, DATA *data);
/**
* 待销毁的队列
* @param q 待操作的队列
*/
extern void lqueue_destroy(LinkQueue *q);
#endif //_LQUEUE_H
```
#### linkqueue.c
#include "lqueue.h"
/**
* 队列初始化(初始属性的赋予)
* @return 成功返回结构体指针q
*/
LinkQueue *lqueue_init()
{
// 分配队列结构体内存
LinkQueue *q = (LinkQueue*)malloc(sizeof(LinkQueue));
// 初始化双指针为NULL表示空队列
q->front = q->rear = NULL;
// 元素计数归零
q->size = 0;
return q;
}
/**
* 判断队列是否为空
* @param q 待操作的队列
* @return 队列为空返回1,否则返回0
*/
extern int lqueue_isempty(LinkQueue *q)
{
return q->front == NULL; //队头指针为空即队列为空
}
/**
* 入队(尾插法)
* @param q 待操作的队列
* @param data 待插入的数据
* @return 成功返回0,否则返回-1
*/
int lqueue_enqueue(LinkQueue *q, DATA data)
{
//创建新节点
NODE *p = (NODE*)malloc(sizeof(NODE));
if(!p)
{
perror("Memory allocation failed!");
return -1;
}
//存储数据
p->data = data;
p->next = NULL; //新节点作为队尾,next置空
//空队列特殊处理
if(q->rear == NULL)
{
q->front = q->rear = p;
}
//非空队列
else
{
//原队尾节点链接新节点
q->rear->next = p;
//更新队尾指针
q->rear = p;
}
//元素计数增加
q->size++;
return 0;
}
/**
* 出队(维护队头指针)---释放队头节点,然后将下一个节点作为新的队头节点
* @param q 待操作的队列
* @param data 接收出队元素的指针
* @return 成功返回0,否则返回-1
*/
int lqueue_dequeue(LinkQueue *q, DATA *data)
{
//判断队列是否为空
if(lqueue_isempty(q))
{
printf("Queue is empty!\n");
return -1;
}
//暂存队头节点
NODE *head = q->front;
//通过指针传出数据
*data = head->data;
//队头指针后移
q->front = head->next;
//如果队列已空,重置rear指针
if(q->front == NULL)
{
q->rear == NULL;
}
free(head); //释放原队头节点内存
//元素计数个数减少
q->size--;
return 0;
}
/**
* 待销毁的队列
* @param q 待操作的队列
*/
void lqueue_destroy(LinkQueue *q)
{
//空指针检查
if(!q)
return;
DATA temp;
//循环出队
while(!lqueue_isempty(q))
{
lqueue_dequeue(q, &temp);
}
free(q); //结构体是动态分配的话就需要释放结构体队列内存
}
```
#### app.c
#include "lqueue.h"
int main(int argc,char *argv[])
{
LinkQueue *q = lqueue_init();
// 入队测试
for (int i = 1; i <= 5; i++) {
lqueue_enqueue(q, i*10);
printf("Enqueued: %d\n", i*10);
}
// 出队测试
int val;
while (!lqueue_isempty(q)) {
lqueue_dequeue(q, &val);
printf("Dequeued: %d\n", val);
}
lqueue_destroy(q);
return 0;
}