数据结构的栈和队列

本文详细介绍了数据结构中的栈和队列的基本概念和实现方式。对于栈,讲解了如何使用数组或指针数组实现,包括初始化、入栈、出栈、查看栈顶元素、判断栈空及销毁栈的操作。对于队列,采用链表结构,实现了初始化、入队、出队、查看队头和队尾元素、判断队列空、获取队列大小以及销毁队列的功能。这些基础知识对于理解和应用数据结构至关重要。
摘要由CSDN通过智能技术生成

目录

1.栈

1、建立栈的基本单元

2、初始化栈

3、入栈

4、出栈

5、查看栈第一个的值和查看数量

6、判空

7、销毁栈

2.队列

1、建立队列的基本单元

2、初始化

3、入队

4、出队

5、判空

6、获取头一个元素和尾元素

7、队列个数

8、销毁队列


1.栈

栈:其数据的存储模式是,后进先出,如下面的筹码一样,假如你一次只能拿取一个,那么你能拿的也就是顶上的筹码,而这种模式就是栈。


1、建立栈的基本单元

基本要素:包括一个存储数据的地方,一个显示已经有多少数的地方,一个容量大小的地方(存储的方式如果是固定的那选用数组,如果需要动态开辟空间就选用指针数组)

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity; 
}Stack;

 

2、初始化栈

外部接受的话,定义一个栈的指针如何传入指针即可(满足改变哪个变量,传入该变量对应的指针,通过函数调用进行改变,所以这里传入栈的指针)

操作:指针指空,容量和个数定义为0

void StackInit(Stack* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

 

3、入栈

注意的是,如果容量和数量一致时说明栈空间已经满了,所以我们需要扩容

操作:判断是否要扩容,将最上方的数赋值,加一已有数量

void StackPush(Stack* ps, StackType x)
{
	assert(ps);

	if (ps->top == ps->capacity)//扩容
	{
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		ps->capacity = newCapacity;
		STDataType* ret = (STDataType*)realloc(ps->a, newCapacity * sizeof(StackType));
		if (ret == NULL)
		{
			perror("malloc fail");
			exit(-1);
		}
		ps->a = ret;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

 

4、出栈

因为控制数多少的边界靠的是已有数多少决定,只操作已有数的内容,因此我们只需要改变栈中已有多少数的大小即可,把已有数减一

void StackPop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}

 

5、查看栈第一个的值和查看数量

说明:top-1就是头一个值

StackType StackTop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->a[ps->top - 1];
}

 说明:top就是有多少数

int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}

 

6、判空

说明:已有数等于0就是空

bool StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top == 0;
}

 

7、销毁栈

void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

 

 

2.队列

队列:如图一样,先来先出

 

1、建立队列的基本单元

因为如果头删会比较麻烦,所以考虑使用链表的形式存储,包含头尾指针方便操作

typedef struct QListNode 
{ 
	struct QListNode* next; 
	QDataType data; 
}QNode; 

typedef struct Queue 
{ 
	QNode* head; 
	QNode* tail; 
}Queue; 

 

2、初始化

void QueueInit(Q_print* pf)
{
	assert(pf);
	pf->head = NULL;
	pf->tail = NULL;
	pf->size = 0;
}

 

3、入队

参考链表的push,在尾处链接一个队列的元素

void QueuePush(Q_print* pf, QueueType x)
{
	assert(pf);
	Queue* tmp = (Queue*)malloc(sizeof(Queue));
	if (tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	tmp->val = x;
	tmp->next = NULL;
	if (pf->head == NULL)
	{
		pf->head = pf->tail = tmp;
	}
	else
	{
		pf->tail->next = tmp;
		pf->tail = pf->tail->next;
	}
	pf->size++;
}

4、出队

头指针指向下一个,释放原先的元素

void QueuePop(Q_print* pf)
{
	assert(pf);
	assert(!QueueEmpty(pf));
	Queue* cur = pf->head;
	pf->head = pf->head->next;
	free(cur);
	pf->size--;
}

5、判空

说明:头指针是否有所指向

bool QueueEmpty(Q_print* pf)
{
	return pf->head == NULL;
}

 

6、获取头一个元素和尾元素

QueueType QueueFront(Q_print* pf)
{
	assert(pf);
	assert(!QueueEmpty(pf));
	return pf->head->val;
}
QueueType QueueBack(Q_print* pf)
{
	assert(pf);
	assert(!QueueEmpty(pf));
	Queue* cur = pf->head;
	while (cur->next)
	{
		cur = cur->next;
	}
	return cur->val;
}

 

7、队列个数

int QueueSize(Q_print* pf)
{
	assert(pf);
	assert(!QueueEmpty(pf));
	return pf->size;
}

8、销毁队列

void QueueDestroy(Q_print* pf)
{
	assert(pf);
	Queue* cur = pf->head;
	if (cur)
	{
		pf->head = pf->head->next;
		free(cur);
	}
	pf->head = pf->tail = NULL;
	pf->size = 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灼榆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值