用循环链表表示队列

假设以带头结点的循环链表表示列队,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的置空队、判队空、入队和出队等算法。


该算法使用循环链表表示列队。

在算法中只设一个指向队尾元素的指针rear,在进行置空队,判队空等操作之前先将队列初始化;

置空队则是将队尾指针指向头结点;

入队则是在队尾插入元素,即在尾结点处插入元素,先申请一个新结点,再将新结点初始化并链入队列最后将尾指针移至新结点;

出队是先判断队列是否为空,不为空则继续接下来的出队操作。


该算法设计了个函数:

函数initQueue()用来初始化列队;

函数emptyQueue()用来将队置空;

函数enqueue()用来将元素链入列队;

函数delqueue()用来将元素出队;


算法流程图

 

用循环链表表示队列

源代码

/*********
date:2021-10-23
author:sy
version:1.0
Description: 以带头结点的循环链表表示列队,只设一个指针指向队尾元素(不设头指针) 
***********/
#include <stdio.h>
#include <stdlib.h>

typedef int elemType;
/*定义结点类型*/ 
typedef struct queuenode
{
	elemType data;
	struct queuenode *next;
}queuenode,*LinkQueue;

typedef struct
{
	LinkQueue rear;  //只设一个指向队尾元素的指针 
	int length;
}sqqueue;

/*初始化列队*/
void initQueue(sqqueue &Q)
{
	Q.rear=(LinkQueue)malloc(sizeof(Q));
	Q.rear->next=Q.rear;
}
/*置空队*/ 
int emptyQueue(sqqueue &Q)
{
	if(Q.rear->next==Q.rear)  //将队尾指针指向头结点 
		return 1;
	else
		return 0;
}
/*入队*/
int enqueue(sqqueue &Q,elemType e)
{   /*在尾结点处插入元素*/
	LinkQueue p;
	p=(LinkQueue)malloc(sizeof(Q));  //申请新结点 
	if(!p)
		return 0;
	/*初始化新结点并链入*/ 
	p->data=e;
	p->next=Q.rear->next;
	Q.rear->next=p;
	Q.rear=p;  //将尾指针移至新结点 
	return 1;
}
/*出队*/
int delqueue(sqqueue &Q,elemType &e)
{
	LinkQueue p;
	if(Q.rear->next==Q.rear)
		return 0;  //若队列为空返回0
	p=Q.rear->next->next;  //循环链表队列队尾指针下一结点(也即头结点)的下一结点(即队头指针)赋给p 
	e=p->data;  // 保存结点中的数据 
	Q.rear->next->next=p->next;  //摘下结点p 
	free(p);   //释放被删结点 
	return 1;
}

int main()
{
	sqqueue m;
	elemType num;
	initQueue(m);
	if(emptyQueue(m))
		printf("该队列目前为空!\n");
	else
		printf("该队列不为空!\n");
	for(int i=1;i<=10;i++)
		{
			if(enqueue(m,i))
			printf("元素%d成功入列!\n",i);
		}
	printf("\n\n");
	for(int j=1;j<=10;j++)
		{
			if(delqueue(m,num))
			printf("元素%d成功出列!\n",num);
		}
	if(emptyQueue(m))
		printf("该队列目前为空!\n");
	else
		printf("该队列不为空!\n");
	return 0;
}

函数delete()与函数free()函数 均可用来释放节点

上一篇:Java面试复习重点:mysql培训文档


下一篇:栈和队列