链队列学习

        链队列是采用链式存储结构实现的队列,通常链队列用单链表来表现。一个队列要入队和出队,所以要有个头指针(队头)和尾指针(队尾),入队时运用尾指针,出队时运用头指针。以下是链队列代码实现和实现结果:

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

typedef struct LinkNode {
	int data;
	struct LinkNode* next;
}*LinkNodePtr;

typedef struct LinkQueue {
	LinkNodePtr front;
	LinkNodePtr rear;
}*LinkQueuePtr;

LinkQueuePtr initQueue()
{
	LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(struct LinkQueue));
	LinkNodePtr headerPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	headerPtr->data = 0;
	headerPtr->next = NULL;

	resultPtr->front = headerPtr;
	resultPtr->rear = headerPtr;

	return resultPtr;
}//off initQueue

void outputLinkQueue(LinkQueuePtr paraQueuePtr)
{
	LinkNodePtr tempPtr = paraQueuePtr->front->next;
	while (tempPtr != NULL)
	{
		printf("%d ", tempPtr->data);
		tempPtr = tempPtr->next;
	}//off while
	printf("\r\n");
}//off outputLinkQueue

void enqueue(LinkQueuePtr paraQueuePtr, int paraElement)
{
	LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	tempNodePtr->data = paraElement;
	tempNodePtr->next = NULL;

	paraQueuePtr->rear->next = tempNodePtr;

	paraQueuePtr->rear = tempNodePtr;
}//off enqueue

int dequeue(LinkQueuePtr paraQueuePtr)
{
	int resultValue;
	LinkNodePtr tempNodePtr;

	if (paraQueuePtr->front == paraQueuePtr->rear)
	{
		printf("the queue is empty\r\n");
		return -1;
	}//off if

	tempNodePtr = paraQueuePtr->front->next;
	resultValue = tempNodePtr->data;
	paraQueuePtr->front->next = paraQueuePtr->front->next->next;
	if (paraQueuePtr->rear == tempNodePtr)
	{
		paraQueuePtr->rear = paraQueuePtr->front;
	}//off if

	free(tempNodePtr);

	return resultValue;
}//off dequeue

void LinkQueueTest()
{
	LinkQueuePtr tempQueuePtr = initQueue();
	enqueue(tempQueuePtr, 10);
	enqueue(tempQueuePtr, 20);
	enqueue(tempQueuePtr, 50);

	outputLinkQueue(tempQueuePtr);

	printf("dequeue get %d\r\n", dequeue(tempQueuePtr));
	printf("dequeue get %d\r\n", dequeue(tempQueuePtr));
	printf("dequeue get %d\r\n", dequeue(tempQueuePtr));

	enqueue(tempQueuePtr, 8);
	outputLinkQueue(tempQueuePtr);
}//off LinkQueueTest

int main()
{
	LinkQueueTest();
	return 0;
}

 1.链队列的结构定义和初始化

 

typedef struct LinkNode {
	int data;
	struct LinkNode* next;
}*LinkNodePtr;

typedef struct LinkQueue {
	LinkNodePtr front;
	LinkNodePtr rear;
}*LinkQueuePtr;

LinkQueuePtr initQueue()
{
	LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(struct LinkQueue));
	LinkNodePtr headerPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	headerPtr->data = 0;
	headerPtr->next = NULL;

	resultPtr->front = headerPtr;
	resultPtr->rear = headerPtr;

	return resultPtr;
}//off initQueue

        这里定义了一个可以存储两个单链表节点的结构体指针LinkQueuePtr,其中front表示单链表的头指针(队头),rear表示单链表的尾指针(队尾)。在链队列的初始化中,定义了空队resultPtr和空表headerPtr,因为当前为空表,所以队头front和队尾rear都指向空表头headerPtr,返回空队resultPtr。

2.入队

void enqueue(LinkQueuePtr paraQueuePtr, int paraElement)
{
	LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	tempNodePtr->data = paraElement;
	tempNodePtr->next = NULL;

	paraQueuePtr->rear->next = tempNodePtr;

	paraQueuePtr->rear = tempNodePtr;
}//off enqueue

       入队时先新给新的队尾tempNodePtr开辟一块空间存储新的数据,让rear->next指向tempNodePtr,再让rear指向新的队尾,实现入队。因为rear初始指向表头headerPtr,移动也是在表头为headerPtr的单链表上移动,所以入队时移动rear本质上是和链表的尾插是一样的,只是表示方法不一样。

3.出队

int dequeue(LinkQueuePtr paraQueuePtr)
{
	int resultValue;
	LinkNodePtr tempNodePtr;

	if (paraQueuePtr->front == paraQueuePtr->rear)
	{
		printf("the queue is empty\r\n");
		return -1;
	}//off if

	tempNodePtr = paraQueuePtr->front->next;
	resultValue = tempNodePtr->data;
	paraQueuePtr->front->next = paraQueuePtr->front->next->next;
	if (paraQueuePtr->rear == tempNodePtr)
	{
		paraQueuePtr->rear = paraQueuePtr->front;
	}//off if

	free(tempNodePtr);

	return resultValue;
}//off dequeue

        就像排队时前出后进一样,出队移出的是队列的第一个节点。出队操作中,当front和rear的地址一致时,表示这个队列是一个空队,也可以说这个表是一个空表,空队列没有存储任何数据(不包括表头headerPtr),所以返回-1。当队列不是一个空队时,用一个整形resultValue接收出队节点的数据,tempNodePtr指向出队节点。让队头front->next指向front->next->next来将出队节点移出队列,再释放tempNodePtr(出队节点)。若此时队尾rear的地址与出队节点相等,说明此节点出队后队列就是个空队,所以让队尾指向队头,完成队列的置空。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
循环队列是一种特殊的队列,其特点是队列的元素在物理结构上是环形排列的。educoder实训教学平台提供了循环队列的基本操作,包括初始化、入队、出队和判空等。 循环队列的初始化操作是创建一个空队列,并设置队列的头指针和尾指针都为0。入队操作是往队尾插入一个元素,插入后尾指针向后移动一位,并将元素放入新的队尾位置。出队操作是将队首元素删除,删除后头指针向后移动一位。判空操作是通过比较队列的头指针和尾指针是否相等来确定队列是否为空。 链队列是使用链表实现的队列,其特点是可以动态地分配内存空间,不会造成内存溢出的问题。educoder实训教学平台也提供了链队列的基本操作,包括初始化、入队、出队和判空等。 链队列的初始化操作是创建一个空队列,并设置头指针和尾指针都指向空节点。入队操作是在链队列的尾部插入一个新节点,尾指针向后移动一位,并将新节点的数据放入新的尾节点。出队操作是删除链队列的头节点,头指针向后移动一位。判空操作是通过判断链队列的头指针和尾指针是否指向同一节点来确定队列是否为空。 通过educoder实训教学平台提供的循环队列和链队列的基本操作,学习者可以掌握数据结构中队列的实现方式和基本操作的原理,进而应用于解决一些实际问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值