队列之链式队列

1、难点

要想用链表实现队列,就必须队尾进,队头出,先进先出,后进后出,这些利用链表的头尾节点都可以实现,即:头删(出队)和尾插(入队),那么如何保证入队出队的**时间复杂度都为O(1)**呢?显然,头删的时间复杂度已经为O(1),因此要让尾插的复杂度为O(1)的话需要将尾节点保存起来。

2、结构体设计

在这里插入图片描述
因此需要进行改进,改进之后的结构体设计如下:
在这里插入图片描述

//有效节点
typedef struct LQueue
{
	ELEM_TYPE data;//用来保存节点数据
	LQueue* next;//用来保存下一个节点地址
}Node, * PNode;

//头节点
typedef struct Head
{
	LQueue* front;//用来保存下一个节点地址
	LQueue* tail;//用来保存最后一个结点的地址,只用头节点保存就行,其他的就会浪费
}head, * Phead;

3、头文件

typedef int ELEM_TYPE;
/*如下设计会让每个节点浪费4字节*/
//typedef struct LQueue
//{
//	ELEM_TYPE* data;//用来保存节点数据
//	LQueue* next;//用来保存下一个节点地址
//	LQueue* tail;//用来保存最后一个结点的地址,只用头节点保存就行,其他的就会浪费
//}Node,*PNode;



//有效节点
typedef struct LQueue
{
	ELEM_TYPE data;//用来保存节点数据
	LQueue* next;//用来保存下一个节点地址
}Node, * PNode;

//头节点
typedef struct Head
{
	LQueue* front;//用来保存下一个节点地址
	LQueue* tail;//用来保存最后一个结点的地址,只用头节点保存就行,其他的就会浪费
}head, * Phead;
//购买节点
PNode Buynode();
//初始化
void Init(Phead pq);
//入队
bool push(Phead pq,ELEM_TYPE val);
//出队
bool Pop(Phead pq, ELEM_TYPE* rtval);
//获取有效节点个数
int Get_length(Phead pq);
//判空
bool Is_Empty(Phead pq);
//清空
void Clear(Phead pq);
//销毁
void Destory(Phead pq);
//打印
void Print(Phead pq);

4、函数实现

#include<stdio.h>
#include<assert.h>
#include"LinkQueue.h"
#include<stdlib.h>
//购买节点
PNode Buynode()
{
	PNode s = (PNode)malloc(sizeof(Node));
	if (s == NULL)
	{
		return NULL;
	}
	return s;
}
//初始化
void Init(Phead pq)
{
	assert(pq != NULL);
	pq->front = pq->tail = NULL;
}
//入队
bool push(Phead pq, ELEM_TYPE val)
{
	assert(pq != NULL);
	PNode s = Buynode();
	s->data = val;
	if (Is_Empty(pq))
	{
		pq->front = s;
		pq->tail = s;
		s->next = NULL;
	}
	else
	{
		s->next = NULL;
		pq->tail->next = s;
		pq->tail = s;
	}
	return true;
}
//出队
bool Pop(Phead pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (Is_Empty(pq))
	{
		return false;
	}
	*rtval = pq->front->data;
	if (pq->front->next == NULL)//只有一个节点
	{
		pq->front = NULL;
		pq->tail = NULL;
	}
	else//有多节点
	{
		PNode p = pq->front;
		pq->front = p->next;
	}
	return true;
}
//获取有效节点个数
int Get_length(Phead pq)
{
	assert(pq != NULL);
	if (Is_Empty(pq))
	{
		return 0;
	}
	PNode p = pq->front;
	int length = 0;
	while (p != NULL)
	{
		length++;
		p = p->next;
	}
	return length;
}
//判空
bool Is_Empty(Phead pq)
{
	assert(pq != NULL);
	return pq->front == NULL;
}
//打印
void Print(Phead pq)
{
	assert(pq != NULL);
	if (Is_Empty(pq))
	{
		return;
	}
	else
	{
		PNode p= pq->front;
		while (p != NULL)
		{
			printf("%d ", p->data);
			p = p->next;
		}
		printf("\n");
	}
}
//清空
void Clear(Phead pq)
{
	assert(pq != NULL);
	pq->front = pq->tail = NULL;
}
void Destory(Phead pq)
{
	assert(pq != NULL);
	Clear(pq);
	free(pq);
	pq = NULL;
}
int main()
{
	Head x = {};
	Phead pq = &x;
	Init(pq);
	for (int i = 0; i < 10; i++)
	{
		push(pq, i);
		Print(pq);
	}
	int rtval;
	for (int i = 0; i < 10; i++)
	{
		Pop(pq, &rtval);
		printf("出栈元素为;%d 剩余%d个元素\n ", rtval,Get_length(pq));
	}
	Destory(pq);
	push(pq, 1);
}

运行结果如下:在这里插入图片描述
当队列中最后一个元素出队之后,我将队列销毁,此时会终止,原因是,每次加的断言,说明销毁成功。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值