数据结构----栈和队列之队列的实现

发布于:2024-07-07 ⋅ 阅读:(36) ⋅ 点赞:(0)

目录

1.基本概况

2.队列组成

3.队列的实现

(1)队列的初始化

(2)队列的销毁

(3)队列的尾插

(4)队列的头删

(5)队列的判空

(6)队列的元素个数

(7)返回头部节点

(8)返回尾部节点

4.完整代码

(1)头文件

(2)源文件

(3)测试文件


1.基本概况

(1)我们之前学习了栈,栈就是先进入,后出来,后进先出,然后使用这个特性解决了括号的匹配问题;

(2)队列就是先进先出,而且是从一头进入,从另外一头出去,栈分为入栈和出栈,队列里面也是分为入队和出队两个部分;

2.队列组成

(1)队列里面的每一个数据也是有自己的next指针和val数值的,但是我们在实现这个在队尾队头插入数据的时候,这个传入这个队头的指针和队尾的指针,而且是二级指针,为什么要传递二级指针,因为我们本身传递的参数就是一个指针,通过这个指针,函数实现的时候才可以找到这个队列的头部尾部节点,我们经过这个插入和删除之后,这个形参的修改时需要同步到实参,但是如果我们传递这个一级指针,就没有办法实现这一点,因此,我们需要传递二级指针;

(2)为什么进行队尾和队头的插入和删除的时候,参数里面是两个指针,一个是头指针,一个是尾指针,插入数据的时候还需要给一个变量作为第三个参数;

(3)这个地方,为了简单起见,我们决定再去定义一个结构体,存放这个头结点和尾结点,这个时候,我们就定义了两个结构体,第一个结构体表示的是每一个节点,这个节点里面包括了这个next指针和val数值,第二个结构体里面包含这个队列的头指针和尾指针;

(4)定义了两个结构体之后,我们就可以把这个结构体作为参数进行传递,因为我们的这个结构体里面是两个一级指针,我们传递参数的时候只需要把这个结构体的指针传递进行就可以了,这个结构体里面就包含了队列的头指针和尾指针;

3.队列的实现

(1)队列的初始化

就是先去断言,然后把这个队列的头尾指针全部置为空指针,节点的个数初始化为0;

(2)队列的销毁

使用循环语句,不断的释放每一个节点,最后再让这个phead和ptail全部置空;

(3)队列的尾插

我们知道这个队列里面的数据都是从队尾进入,所以这个push也是从队尾去插入数据,我们需要手动的开辟新的节点空间;

如果这个队列本来就是空的,这个时候队列的头节点和尾结点都是newnode,否则的话,这个头结点不变,尾结点更新一下就可以了,使用if  else实现这个功能;

(4)队列的头删

我们的队列里面的数据从头部出来,简称头部删除,我们需要判断这个队列里面的元素的个数,如果这个队列里面只有一个节点,这个时候ptail和phead都是指向的这个节点,我们把任意的一个空间释放掉,另外一个就会变成野指针;

因此我们进行判断,如果只有一个节点,释放完空间之后,把这个ptail和phead都置为空指针;否则就把这个next节点记录下来,删除旧的节点之后,让我们的next成为新的头结点;

(5)队列的判空

直接判断这个pq->size==0即可,如果是0,就说明这个队列里面没有数据,返回值bool就是0,有数据的话就返回的是1;

(6)队列的元素个数

pq->size就是这个队列里面的节点的个数,直接返回即可;

(7)返回头部节点

返回头部节点,pq这个队列不可以是空的,而且这个队列的头结点不可以是空的,否则我们的这个目的就无法达到;

(8)返回尾部节点

返回尾部节点,这个队列不可以是空的,而且这个队列的尾部节点不可以是空的,否则无法找到这个节点里面的val数值;

4.完整代码

(1)头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int qdatatype;

typedef struct quenenode
{
	struct quenenode* next;
	qdatatype val;
}qnode;

//队列的一个特点就是先进先出,后进后出

typedef struct quene
{
	qnode* phead;
	qnode* ptail;
	int size;
}quene;

void queneinit(quene* pq);

void quenedestory(quene* pq);

void quenepush(quene* pq, qdatatype x);

qdatatype queneback(quene* pq);

qdatatype quenefront(quene* pq);

int quenesize(quene* pq);

bool queneempty(quene* pq);

(2)源文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"quene.h"

void queneinit(quene* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void quenedestory(quene* pq)
{
	assert(pq);
	qnode* cur = pq->phead;
	while (cur)
	{
		qnode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
}

void quenepush(quene* pq, qdatatype x)
{
	assert(pq);
	qnode* newnode = (qnode*)malloc(sizeof(qnode));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		return;
	}
	newnode->next = NULL;
	newnode->val = x;
	if (pq->ptail == NULL)
	{
		pq->ptail = pq->phead = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}
//出队列,从头部删除数据
void quenepop(quene* pq)
{
	assert(pq);
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		qnode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}

qdatatype queneback(quene* pq)
{
	assert(pq);
	assert(pq->ptail);
	return pq->ptail->val;
}

qdatatype quenefront(quene* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->val;
}

int quenesize(quene* pq)
{
	assert(pq);
	return pq->size;
}

bool queneempty(quene* pq)
{
	assert(pq);
	return pq->size == 0;
}

(3)测试文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"quene.h"
void test01()
{
	quene q;
	queneinit(&q);
	quenepush(&q, 1);
	quenepush(&q, 2);
	quenepush(&q, 3);
	quenepush(&q, 4);
	while (!queneempty(&q))
	{
		printf("%d ", quenefront(&q));
		quenepop(&q);
	}
	printf("\n");
}
int main()
{
	test01();
	return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到