数据结构8:队列和循环队列

链队列

链队列是用一个线性链表来表示一个队列,队列中每一个元素对应链表中一个链结点,这样的队列简称链接队列。具体地说,把线性链表第1个链结点的指针定义为队头指针front,在链表最后的链结点建立指针rear作为队尾指针,并且限定只能在链头进行删除操作,在链尾进行插入操作,这个线性链表就构成了一个链接队列。另一个与顺序存储队列的不同点是,队头指针与队尾指针都是指向实际队头元素与队尾元素所在的链结点。

基本操作

1.定义(定义节点和队列,方便操作)

//链队列节点
typedef struct LinkNode
{
	int data;
	struct LinkNode* next;
}*LinkNodePtr;

//链队列 
typedef struct LinkQueue
{
	LinkNodePtr front;
	LinkNodePtr rear;
 } *LinkQueuePtr;

2.初始化

//初始化
LinkQueuePtr initQueue() 
{
	LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(struct LinkQueue));
	LinkNodePtr headPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	headPtr->data = -1;
	headPtr->next = NULL;
	resultPtr->front = headPtr;
	resultPtr->rear = headPtr;
	return resultPtr;
 }

3.打印

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

 

4.入队

//入队
void enterQueue(LinkQueuePtr paraQueuePtr,int paraElem)
{
	LinkNodePtr tempPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	tempPtr->data = paraElem;
	tempPtr->next = NULL;
	
	paraQueuePtr->rear->next = tempPtr;
	paraQueuePtr->rear = tempPtr;	
 } 

5.出队

//出队
int deleteQueue(LinkQueuePtr paraQueuePtr)
{
	int result;
	LinkNodePtr tempPtr;
	//判断队列是否为空
	if(paraQueuePtr->front == paraQueuePtr->rear)
	{
		printf("队列为空,不能删除\n");
		return -1;
	 } 
	tempPtr = paraQueuePtr->front->next;
	result = tempPtr->data;
	paraQueuePtr->front->next = tempPtr->next;
	if(paraQueuePtr->rear == tempPtr)
	{
		paraQueuePtr->rear = paraQueuePtr->front;
	}
	free(tempPtr);
	return result;
 }

功能测试及结果

//功能测试
void queueText()
{
	LinkQueuePtr tempQueue = initQueue();
	enterQueue(tempQueue,5);
	enterQueue(tempQueue,10);
	enterQueue(tempQueue,15);
	enterQueue(tempQueue,20);
	outputQueue(tempQueue);
	printf("删除%d\n",deleteQueue(tempQueue));
	printf("删除%d\n",deleteQueue(tempQueue));
	outputQueue(tempQueue);
	printf("删除%d\n",deleteQueue(tempQueue));
	printf("删除%d\n",deleteQueue(tempQueue));
	printf("删除%d\n",deleteQueue(tempQueue));
	enterQueue(tempQueue,13);
	outputQueue(tempQueue);
 } 
5 10 15 20
删除5
删除10
15 20
删除15
删除20
队列为空,不能删除
删除-1
13

循环队列

        循环队列就是将一般队列首尾相连,形成一个环状队列,有利于更好地利用空间。

基本操作

1.定义 

//循环队列
typedef struct CircleQueue
{
	int data[TOTAL_SPACE];
	int head;//队首 
	int tail;//队尾 
 } *CircleQueuePtr;

 2.初始化

//初始化
CircleQueuePtr initCircleQueue()
{
	CircleQueuePtr resultPtr = (CircleQueuePtr)malloc(sizeof(struct CircleQueue));
	resultPtr->head = 0;
	resultPtr->tail = 0;
	return resultPtr;
}

3.打印 

//打印
void outputQueue(CircleQueuePtr paraPtr)
{
	int i;
	if(paraPtr->head == paraPtr->tail)
	{
		printf("队列为空.\n");
		return;
	}
	printf("队列:");
	for(i = paraPtr->head;i < paraPtr->tail;i++)
	{
		printf("%d ",paraPtr->data[i % TOTAL_SPACE]);
	}
	printf("\n");
 } 

4.入队

//入队
void enterQueue(CircleQueuePtr paraPtr,int paraData)
{
	if((paraPtr->tail+1) % TOTAL_SPACE == paraPtr->head)
	{
		printf("队列已满.\n");
		return;
	}
	paraPtr->data[paraPtr->tail%TOTAL_SPACE] = paraData;
	paraPtr->tail++;
 } 

5.出队

//出队 
int deleteQueue(CircleQueuePtr paraPtr)
{
	int result;
	if(paraPtr->head == paraPtr->tail)
	{
		printf("队列为空,不能删除.\n");
		return -1;
	}
	result = paraPtr->data[paraPtr->head % TOTAL_SPACE];
	paraPtr->head++;
	return result;
 } 

功能测试及结果

//测试
void queueText()
{
	CircleQueuePtr tempPtr = initCircleQueue();
	int i;
	for(i = 9;i < 15;i++)
	{
		enterQueue(tempPtr,i);
	}
	outputQueue(tempPtr);
	for(i = 0;i < 4;i++)
	{
		printf("删除%d\n",deleteQueue(tempPtr));
	}
	outputQueue(tempPtr);
	for(i = 0;i<3;i++)
	{
		printf("删除%d\n",deleteQueue(tempPtr));
	}
 }
队列已满.
队列:9 10 11 12 13
删除9
删除10
删除11
删除12
队列:13
删除13
队列为空,不能删除.
删除-1
队列为空,不能删除.
删除-1

总代码

链队列

#include <stdio.h>
#include <malloc.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 headPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	headPtr->data = -1;
	headPtr->next = NULL;
	resultPtr->front = headPtr;
	resultPtr->rear = headPtr;
	return resultPtr;
 }

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

//入队
void enterQueue(LinkQueuePtr paraQueuePtr,int paraElem)
{
	LinkNodePtr tempPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	tempPtr->data = paraElem;
	tempPtr->next = NULL;
	
	paraQueuePtr->rear->next = tempPtr;
	paraQueuePtr->rear = tempPtr;	
 } 

//出队
int deleteQueue(LinkQueuePtr paraQueuePtr)
{
	int result;
	LinkNodePtr tempPtr;
	//判断队列是否为空
	if(paraQueuePtr->front == paraQueuePtr->rear)
	{
		printf("队列为空,不能删除\n");
		return -1;
	 } 
	tempPtr = paraQueuePtr->front->next;
	result = tempPtr->data;
	paraQueuePtr->front->next = tempPtr->next;
	if(paraQueuePtr->rear == tempPtr)
	{
		paraQueuePtr->rear = paraQueuePtr->front;
	}
	free(tempPtr);
	return result;
 }

//功能测试
void queueText()
{
	LinkQueuePtr tempQueue = initQueue();
	enterQueue(tempQueue,5);
	enterQueue(tempQueue,10);
	enterQueue(tempQueue,15);
	enterQueue(tempQueue,20);
	outputQueue(tempQueue);
	printf("删除%d\n",deleteQueue(tempQueue));
	printf("删除%d\n",deleteQueue(tempQueue));
	outputQueue(tempQueue);
	printf("删除%d\n",deleteQueue(tempQueue));
	printf("删除%d\n",deleteQueue(tempQueue));
	printf("删除%d\n",deleteQueue(tempQueue));
	enterQueue(tempQueue,13);
	outputQueue(tempQueue);
 } 

int main()
{
	queueText();
}

循环队列

#include <stdio.h>
#include <malloc.h>

#define TOTAL_SPACE 6

//循环队列
typedef struct CircleQueue
{
	int data[TOTAL_SPACE];
	int head;//队首 
	int tail;//队尾 
 } *CircleQueuePtr;

//初始化
CircleQueuePtr initCircleQueue()
{
	CircleQueuePtr resultPtr = (CircleQueuePtr)malloc(sizeof(struct CircleQueue));
	resultPtr->head = 0;
	resultPtr->tail = 0;
	return resultPtr;
}

//打印
void outputQueue(CircleQueuePtr paraPtr)
{
	int i;
	if(paraPtr->head == paraPtr->tail)
	{
		printf("队列为空.\n");
		return;
	}
	printf("队列:");
	for(i = paraPtr->head;i < paraPtr->tail;i++)
	{
		printf("%d ",paraPtr->data[i % TOTAL_SPACE]);
	}
	printf("\n");
 } 
//入队
void enterQueue(CircleQueuePtr paraPtr,int paraData)
{
	if((paraPtr->tail+1) % TOTAL_SPACE == paraPtr->head)
	{
		printf("队列已满.\n");
		return;
	}
	paraPtr->data[paraPtr->tail%TOTAL_SPACE] = paraData;
	paraPtr->tail++;
 } 
 
//出队 
int deleteQueue(CircleQueuePtr paraPtr)
{
	int result;
	if(paraPtr->head == paraPtr->tail)
	{
		printf("队列为空,不能删除.\n");
		return -1;
	}
	result = paraPtr->data[paraPtr->head % TOTAL_SPACE];
	paraPtr->head++;
	return result;
 } 
 
//测试
void queueText()
{
	CircleQueuePtr tempPtr = initCircleQueue();
	int i;
	for(i = 9;i < 15;i++)
	{
		enterQueue(tempPtr,i);
	}
	outputQueue(tempPtr);
	for(i = 0;i < 4;i++)
	{
		printf("删除%d\n",deleteQueue(tempPtr));
	}
	outputQueue(tempPtr);
	for(i = 0;i<3;i++)
	{
		printf("删除%d\n",deleteQueue(tempPtr));
	}
 }

int main()
{
	queueText();
 } 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值