队列(Queue)的链式实现详解----线性结构

昨天分享了栈的链式实现,今天有空也把队列的链式实现也为大家分享一下。

队列(Queue) 也是线性表的一种重要的 受限型数据结构,见名思义,队列就是抽象概括生活中的现象。

如我们在进行生活中进行排队时,我们一般都是从队尾进入队伍,然后等待处于队头的人逐渐出队,即每个人只能从队尾rear进行入队,从队头front进行出队,只允许单进单出,这就是队列数据结构的基本特征。

我们把队列的这种的特性叫做FIFO(先进先出)

与之对应的是栈的特性LIFO(后进先出),详情请看上篇文章。

称从队尾rear入队的操作为----->入队
称从队头front出队的操作为----->出队

由于队列的操作比较简单一些,在此不再详细赘述,如果小伙伴们有疑虑,欢迎留言评论~

下面直接给出队列的链式实现代码

初始化队列(Queue)

//数据结构---->初始化链式队列 
int initQueue(LinkQueue &queue)
{
    
    
	queue = (QueueNode *)malloc(sizeof(QueueNode));			//使用malloc函数动态为队列开辟空间 
	queue->front = NULL;				//队列头指针初始化指向NULL 
	queue->rear = NULL;					//队列尾指针初始化指向NULL 
	
	return OK;				//返回成功信息 
}

入队操作(enterQueue)

对队列的尾部进行插入元素操作,即入队操作


//数据结构---->向队尾进行插入元素操作,即入队操作 
int enterQueue(LinkQueue &queue, Student student)
{
    
    
	Student *student1 = (Student *)malloc(sizeof(Student));			//动态开辟队列结点元素 
	
	student1->id = student.id; 
	student1->age = student.age;			//为待插入结点添加信息 
	
	
	if(queue->front == NULL && queue->rear == NULL)			//若队列为空队列 
	{
    
    
		queue->front = student1;			//队头指针front指向该元素 
		queue->rear = student1;				//队尾指针rear指向该元素 
	}
	else						//若队列不为空队列 
	{
    
    
		queue->rear->next = student1;		//将该元素从队列尾部插入队列 
		queue->rear = student1;				//队尾指针rear后挪,指向该元素 
	}
	
	queue->rear->next = NULL;		//队尾的下一待加入元素设置为NULL 
	
	return OK;				///返回 
}

出队操作(quitQueue)

将队列头部的元素进行去除出队,即出队操作


//数据结构---->将队列头部的元素进行去除,即出队操作 
int quitQueue(LinkQueue &queue, Student &student)
{
    
    
	Student *q = queue->front;			//定义指针q暂时保存队头元素 
	
	if(queue->front == NULL && queue->rear == NULL)		//若队列为NULL 
		return ERROR;					//返回出队失败信息 
	
	if(queue->front == queue->rear)		//若队列仅有一个元素 
	{
    
    
		queue->front = NULL; 
		queue->rear = NULL;				//直接队头、队尾指针设置为NULL,恢复空队列 
	}
	else			//若队列中的元素大于 1 (length>1) 
	{
    
    
		queue->front = queue->front->next; 		//队列的队头直接指向队列头的下一元素 
	}
	
	free(q);		//释放原队列头部 
	return OK;		//返回 
}

获取队列的头元素(getHead)

//数据结构---->获取队列头元素 
int getHead(LinkQueue &queue, Student &student)
{
    
    
	if(queue->front != NULL)			//若队列头部存在元素 
	{
    
    
		student = *queue->front;		//保存下该元素的信息 
		return OK;					//返回结果 
	}
	else
		return ERROR;				//否则返回失败信息 
}

队头至队尾输出所有队列

//数据结构---->从队列头部至队列尾部输出队列 
void queueTraverse(LinkQueue &queue)
{
    
    
	int i = 0;			//定义统计量 
	Student *student = queue->front;		//定义遍历队列变量student 
	
	printf("队列头部至队列尾部所有元素的信息如下:\n");
	while(student != NULL)					//循环从头遍历至尾 
	{
    
    
		printf("id = %d, age = %d.\n", student->id, student->age);		//输出结点信息 
		i++;
		student = student->next;			//遍历指针后挪队列下一结点 
	}
	printf("共有 %d 条数据.\n\n", i);		//输出数据条数 
	
	return;			//返回 
}

销毁、清空队列,判断空队列和求队列长度

//数据结构---->销毁队列 
int destroyQueue(LinkQueue &queue)
{
    
    
	clearQueue(queue);		//首先将队列清空 
	free(queue);			//释放队列的地址空间 
	queue = NULL;			//队列指针设置为NULL 
	return OK;		//返回 
}


//数据结构---->清空队列元素 
int clearQueue(LinkQueue &queue)
{
    
    
	Student student;		//定义临时变量 
	while(queue->front != NULL && queue->rear != NULL)		//若队列仍有元素 
		quitQueue(queue, student);						//不断进行出队操作 
	return OK;				//返回 
}


//数据结构---->判断队列是否为空 
int queueEmpty(LinkQueue &queue)
{
    
    
	if(queue->front == NULL && queue->rear == NULL)
		return TRUE;			//若队列为NULL,返回true 
	else
		return FALSE;			//否则返回false 
}


//数据结构---->测试队列的长度 
int queueLength(LinkQueue &queue)
{
    
    
	int i = 0;			//定义计数器i并初始化为 0 
	Student *student = queue->front;			//定义指针student指向队列头元素 
	while(student != NULL)				//循环累计
	{
    
    
		i++;			//计数器累加 
		student = student->next;		//student指针不断向队尾进行移动 
	}
	return i;			//返回计数结果 
}

好啦,这就是队列的基本操作,还有例如双端队列、循环队列等较为复杂的队列,以后有空研究再补上来,小伙伴们如有疑问欢迎留言评论,加油~

猜你喜欢

转载自blog.csdn.net/weixin_43479947/article/details/113487086