数据结构——队列(链队列)

链队列图示:

 头结点需要两个指针域(一个指向头元素,一个指向尾元素),不需要数据域,所以头结点单独设计。

链队列头结点设计:

//头结点的结构体设计:
typedef struct LQueue
{
	struct Node* front;
	struct Node* rear;
}LQueue, * PLQueue;

链队列有效结点设计:

//链队列的结构体设计
typedef int ELEM_TYPE;

//有效数据节点的结构体设计:
typedef struct Node
{
	ELEM_TYPE data;//数据域
	struct Node* next;//指针域
}Node, * PNode;

可执行函数声明:

//初始化 
void Init_LQueue(struct LQueue* lq);

//入队
bool Push(struct LQueue* lq, ELEM_TYPE val);

//出队(这里需要知道出队的值,通过输出参数rtval带出来)
bool Pop(struct LQueue* lq, ELEM_TYPE* rtval);

//获取队头元素值(这里需要知道队头的值,通过输出参数rtval带出来)
bool Top(struct LQueue* lq, ELEM_TYPE* rtval);

//搜索
struct Node* Search(struct LQueue* lq, ELEM_TYPE val);

//判空
bool IsEmpty(struct LQueue* lq);

//判满(链式结构 不需要判满)

//获取有效长度
int Get_length(struct LQueue* lq);

//清空
void Clear(struct LQueue* lq);

//销毁
void Destroy(struct LQueue* lq);

//打印
void Show(struct LQueue* lq);

代码 :

初始化:

//初始化 
void Init_LQueue(struct LQueue* lq)
{
	assert(lq != NULL);
	lq->front = lq->rear = NULL;
}

入队:

bool Push(struct LQueue* lq, ELEM_TYPE val)
{
	assert(lq != NULL);
	PNode pnewnode = (PNode)malloc(sizeof(Node) * 1);
	assert(pnewnode != NULL);
	pnewnode->data = val;

	if (IsEmpty(lq))//特殊情况下插入:空队列
	{
		pnewnode->next = lq->front;

		lq->front = lq->rear = pnewnode;//因为如果是一个空队列,那么你入队的元素则既是队头也是队尾
	}
	else//正常情况下插入:插入的时候,里面有元素,不是一个空队列
	{
		pnewnode->next = lq->rear->next;
		lq->rear->next = pnewnode;

		lq->rear = pnewnode;//别忘了:更新一下队尾指针,重新让它指向新插入的尾结点
	}
	return true;
}

出队:

//出队(这里需要知道出队的值,通过输出参数rtval带出来)
bool Pop(struct LQueue* lq, ELEM_TYPE* rtval)
{
	assert(lq != NULL);
	if (IsEmpty(lq))
	{
		return false;
	}
	*rtval = lq->front->data;
	//if(lq->front->next == NULL)//ok 判断剩余元素是否仅剩下一个
	if (Get_length(lq) == 1)//ok
	{
		struct Node* p = lq->front;
		free(p);

		lq->front = lq->rear = NULL;
	}
	else //正常情况下: 剩余元素不止一个
	{
		struct Node* p = lq->front;

		lq->front = p->next;
		free(p);
	}

	return true;
}

获取队头元素、搜索

//获取队头元素值(这里需要知道队头的值,通过输出参数rtval带出来)
bool Top(struct LQueue* lq, ELEM_TYPE* rtval)
{
	assert(lq != NULL);
	if (IsEmpty(lq))
	{
		return false;
	}
	*rtval = lq->front->data;
	return true;
}

//搜索
struct Node* Search(struct LQueue* lq, ELEM_TYPE val)
{
	assert(lq != NULL);
	//这里用的是 不需要前驱的for循环 ,遍历一遍即可
	for (struct Node* p = lq->front; p != NULL; p = p->next)
	{
		if (p->data == val)
		{
			return p;
		}
	}

	return NULL;
}

判空,判满、获取有效长度

//判空
bool IsEmpty(struct LQueue* lq)
{
	assert(lq!= NULL);
	return lq->front  == NULL;
}

//判满(链式结构 不需要判满)

//获取有效长度
int Get_length(struct LQueue* lq)
{
	assert(lq != NULL);
	int cout = 0;
	for (PNode p = lq->front; p != NULL; p = p->next)
	{
		cout++;
	}
	return cout;
}

清空,销毁,打印

//清空
void Clear(struct LQueue* lq)
{
	assert(lq != NULL);
	Destroy(lq);
}

//销毁
void Destroy(struct LQueue* lq)
{
	assert(lq != NULL);
	PNode p = lq->front;
	struct Node* q;
	while (p != NULL)
	{
		q = p->next;
		free(p);
		p = q;
	}
	lq->front = lq->rear = NULL;
}

//打印
void Show(struct LQueue* lq)
{
	assert(lq != NULL);
	PNode p = lq->front;
	for (p; p != NULL; p = p->next)
	{
		printf("%d ", p->data);
	}
	printf("\n");
}

测试:

int main()
{
	struct LQueue head;//建立一个头结点
	Init_LQueue(&head);//初始化这个头结点

	for(int i=0; i<20; i++)
	{
		Push(&head, i+1);//将1到20入队
	}
	Show(&head);//打印1到20

	ELEM_TYPE tmp;
	bool tag = Pop(&head, &tmp);
	if(tag)
	{
		printf("pop = %d\n", tmp);
	}//出队1,并且打印出队的元素
	Show(&head);//打印2到20
	printf("length = %d\n", Get_length(&head));//打印有效长度

	ELEM_TYPE flag;
	bool tag2 = Top(&head, &flag);
	if(tag2)
	{
		printf("Top = %d\n", flag);
	}//获取队头元素(没有删除)
	Show(&head);//打印20到20
	printf("length = %d\n", Get_length(&head));//打印有效长度

	Destroy(&head);//销毁
	Show(&head);//打印
	printf("length = %d\n", Get_length(&head));//打印有效长度

	return 0;
}

测试结果:

 没有内存泄漏!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值