数据结构——队列

队列

我们已经知道,栈是一种后进先出的顺序表,二队列是一种先进先出的顺序表,就像我们日常生活中排队结账,排队上公交车,先到先享受一样,那么在c语言中,队列与栈一样,都可以用顺序表链表实现,之前栈使用顺序表来实现的,比较好操作,但是队列就不一样,你要记录队头元素,以及队尾元素,就需要两个指针来记录,所以我们采用链表来实现队列。

队列的基本操作有以下接口

typedef int type   //可自行定义队列中每个结点的数据类型
typedef struct qnode      //队列结点的创建
{
  struct qnode* next;
  type data;
}qnode;
typedef struct queue    //队头,队尾指针的创建以及队列大小
{
  qnode* front;//头指针
  qnode* rear;//尾指针
  size_t size;   //大小没有负
}queue;
void queueinit(queue* q);   //队列的初始化
qnode* creatnode(type data);  //结点创建
void queuepush(queue* q,type data);    //入队
void queuepop(queue* q);    //出队
type queuefront(queue* q);    //获取对头元素
type queueback(queue* q);    //获取队尾元素
size_t queuesize(queue* q);   //当前队列大小
int queueempty(queue* q);    //判断队列是否为空
void queuedestory(queue* q);   //队列的销毁

接下来就一个接口一个接口的看吧

初始化

在这个接口中,需要对队列的头尾指针以及大小进行初始化,代码较简单,如下

void queueinit(queue* q)
{
	q-front = q->rear = NULL;  //头尾指针赋空
	q->size = 0; //当前初始化大小为0
}

队列结点创建

创建节点后,要注意防止野指针出现,该接口也较为简单,代码如下

qnode* creatnode(type data)
{
	qnode* node = (qnode*)malloc(sizeof(type)); // 通过动态内存申请空间
	node->next = NULL; //next指针赋空
	node->data = data;//结点数据赋值
	return node;//返回这个创建的结点
}

入队

入队操作需要注意,要改变尾指针的指向,并且队列的size要增加1,与链表的尾插较为相似,具体接口代码如下

void queuepush(queue* q,type data)
{
	if(q==NULL)
		return ;//若队列不存在,直接返回空
	qnode* node = creatnode(data);  
	if(q->front==NULL)  //判断队列是否有首元素
		q->front = q->rear = node; //头尾指向第一个结点
	else{
		q->rear->next = node;  //尾结点指向下一个结点
		q->rear = node;  //尾指针改变
	}
	q->size++; //队列大小加1
}

出队

出队的时候,需要注意的是队列是否为空,如果为空,则表示出队失败,否则出队成功,出队后,当前的size需要减1。具体代码如下

void queuepop(queue* q)
{
	if(q->front)  //判断当前队列不为空
	{
		qnode* tmp = q->front; 	//临时结点方便释放
		free(q->front);	//释放头节点
		q-front = tmp->next;	//头指针指向下一个结点
		if(q->front==NULL)	//如果删除的是最后一个结点
			q->rear = NULL;	//尾指针置空
		q->size--;	//队列大小减1
	}
}

获取队头元素

返回队头元素数据

type queuefront(queue* q)
{
	if(q->freon)
		return q->front->data;
}

获取队尾元素

返回队尾元素数据

type queueback(queue* q)
{
  if(q->rear)
    return q->rear->data;
}

获取当前队列大小

返回当前队列大小

size_t queuesize(queue* q)
{
	return q->size;
}

判断队列是否为空

通过头指针size大小判断

int queueempty(queue* q)
{
  if(q->front==NULL)
    return 1;  //空则返回1
  return 0;//非空返回0
}

销毁队列

这里和链表的销毁差不多,值得注意的是需要将头尾指针置空以及size置0,

void queuedestory(queue* q)
{
	qnode* tmp = q->front;  //获取队头以方便遍历释放
	while(tmp)
	{
		qnode* p = tmp->next;  //记录下一个需要释放结点
		free(tmp);   //释放当前结点
		tmp = q;  //找到下一个结点
	}
	q->front = q->rear = NULL;  //头尾指针赋空
	q->size = 0;   //队列大小置0
}

总结

队列的实现在这里用的是链式结构,当然也可以通过顺序表来实现,循环队列的实现通常就是用顺序表来实现,下次我会写出循环队列的实现,方便大家参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值