C语言实现链式队列

目录

前言

1. 头文件的实现

1.1 定义队列数据类型

1.2 定义队列元素结构体

1.3 定义队列结构体

1.4 定义相关函数

2. 源文件的实现

2.1 队列生成函数实现

2.2 入队函数实现

2.3 出队函数实现

2.4 空队判断实现

2.5 清空队列实现

 2.6 释放队列实现

3. 代码测试


前言

链式队列(Linked Queue)是一种基于链表实现的队列数据结构。在链式队列中,每个元素都由一个节点表示,每个节点包含两部分:数据部分和指向下一个节点的指针部分。队列的头部通过链表的头指针表示,队列的尾部通过链表的尾指针表示。链式队列示意图如下图所示

图1 链式队列示意图

链式队列相比顺序队列的优势在于可以动态地分配内存空间,不受固定容量的限制。当需要入队时,只需在链表尾部新增一个节点;当需要出队时,只需删除链表头部的节点。这种设计使得链式队列对于频繁的入队和出队操作更为高效。

需要注意的是,在使用链式队列时要注意处理好指针的连接与更新,以避免出现内存泄漏或指针错乱等问题,接下来我们就分模块实现一下,然后编写一个测试代码进行测试: 

1. 头文件的实现

1.1 定义队列数据类型

typedef int datatype;

1.2 定义队列元素结构体

这里就是队列元素的定义,结构体内容包括数据和下一个元素的指针。

typedef struct node {
	datatype data;
	struct node *next; 
}listnode ,*linklist;

1.3 定义队列结构体

这里就是队列结构体的定义,包括头节点、尾节点的指针。

typedef struct {
	linklist front;
	linklist rear;
}linkqueue;

1.4 定义相关函数

定义初始化、入队、出队等相关函数。

linkqueue *queue_create();
int enqueue(linkqueue* lq,datatype x);
datatype dequeue(linkqueue *lq);
int queue_empty(linkqueue *lq);
int queue_clear(linkqueue *lq);
linkqueue* queue_free(linkqueue *lq);

2. 源文件的实现

2.1 队列生成函数实现

开辟队列空间和一个队列元素空间,将队列的front和rear指向这一个元素,并队这个元素的数据进行赋值(赋值多少无所谓),将队列元素的指向置为NULL。

linkqueue *queue_create()
{
	linkqueue *lq;
	if((lq= (linkqueue*)malloc(sizeof(linkqueue))) == NULL){//开辟队列空间
		printf("malloc linkqueue failed\n");
		return NULL;
	}

	lq->front = lq->rear = (linklist)malloc(sizeof(listnode));//开辟队列元素空间
	if(lq->front == NULL)
	{
		printf("malloc node failed\n");
	}
	lq->front->data = 0;//进行队列front的初始化
	lq->front->next = NULL;

	return lq;
}

2.2 入队函数实现

链式队列入队如图所示

图2 入队示意图

需要注意的就是将队列的rear指向新生成的队列元素,下面进行队列入队函数的实现 。

int enqueue(linkqueue* lq,datatype x)
{
	if(lq == NULL){//判断队列是否为空
		printf("malloc linkqueue failed\n");
		return -1;
	}

	linklist p = (linklist)malloc(sizeof(listnode));//开辟队列元素空间
	if(p ==NULL)
	{
		printf("malloc node failed\n");
		return -1;
	}
	p->data = x;//定义待入队元素的数值
	p->next = NULL;//定义待入队元素的下一个指向位置默认为NULL
	lq->rear->next = p;//入队
	lq->rear = p;

	return 0;
}

2.3 出队函数实现

链式队列出队如图所示

 图3 出队示意图

这里我们做一个出队技巧,不需要操作队尾指针,直接将队列的第一个元素当作队头。

进行队列出队函数的实现

datatype dequeue(linkqueue *lq)
{
	
	if(lq == NULL){//判断队列指针是否为空
		printf("malloc linkqueue failed\n");
		return -1;
	}
	linklist p;

	p = lq->front;//出队技巧,不需要操作队尾指针,将队列的第一个元素当作队头
	lq->front = p->next;
	free(p);
	p = NULL;
	
	return (lq->front->data);
}

2.4 空队判断实现

进行队列是否为空的判断实现

图4 空队示意图 

若队头指针等于队尾指针,则为空

int queue_empty(linkqueue *lq)
{
	if(lq == NULL){//判断队列指针是否为空
		printf("malloc linkqueue failed\n");
		return -1;
	}
	return (lq->front == lq->rear ? 1 : 0);//若队头指针等于队尾指针,则为空
}

2.5 清空队列实现

当队列的头元素指向的第一个的元素存在时,就clear,这里也是用的出队技巧

int queue_clear(linkqueue *lq)
{
	
	if(lq == NULL){//判断队列指针是否为空
		printf("malloc linkqueue failed\n");
		return -1;
	}

	linklist p;
	while(lq->front->next)//当队列的头元素指向的第一个的元素存在时,就clear,这里也是用的出队技巧
	{
		p = lq->front;
		lq->front = p->next;
		printf("clear:%d\n",p->data);
		free(p);
		p = NULL;
	}
}

 2.6 释放队列实现

linkqueue* queue_free(linkqueue *lq)
{
	if(lq == NULL){//判断队列指针是否为空
		printf("malloc linkqueue failed\n");
		return NULL;
	}
	linklist p;
	while(lq->front)//这里释放掉全部的队列元素,包括头元素
	{
		p = lq->front;
		lq->front = p->next;
		printf("free:%d\n",p->data);
		free(p);
	}

	free(lq);//释放队列
	lq = NULL;

	return NULL;
}

3. 代码测试

上面我们已经完成了队列的实现了,接下来我们编写一个测试代码进行功能测试。我们要实现的功能为:输入数字入队,输入字符出队。下面是我的test.c代码展示:

#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"

int main(int argc,const char *argv[])
{
	linkqueue *lq;
	lq = queue_create();
	if(lq==NULL)
		return -1;
	char input[10];
	printf("please Num or Char\n");
	while(1)
	{
		scanf("%s",input);
		if(input[0]>='0'&&input[0]<='9')
		{
			enqueue(lq,atoi(input));
		}
		else
		{
			if(!queue_empty(lq))
			{
				printf("dequeue:%d\n",dequeue(lq));
			}
		}
	}

	return 0;
}

代码测试结果如下,成功!!! 

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值