大数据最全【数据结构】我家三岁表弟都明白的栈和队列,你不会不了解吧?,音视频时代你还不会NDK开发

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取


一、栈

1.栈的基本概念

栈是只允许在一端进行插入或删除操作的线性表。首先栈是一种线性表,但是对其限定该线性表只能在某一端进行插入或删除操作。
  栈顶:进行数据插入和删除操作的一端;
  栈底:不允许进行插入和删除的另一端;
  空栈:不含任何元素的空表。

栈中的元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
  出栈:栈的删除操作叫做出栈。出数据也在栈顶。

在这里插入图片描述

2.栈的顺序存储(数组实现)

栈是一种操作受限的线性表,可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
  采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元(数组)存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶元素的位置。

栈的顺序存储类型描述如下:
typedef int SDataType;

typedef struct Stack
{
	SDataType\* array;
	int capacity; //栈的容量
	int top; //栈的元素个数
}Stack;

2.1 栈的初始化
void StackInit(Stack\* ps)
{
	assert(ps);
	ps->array = (SDataType\*)malloc(sizeof(SDataType)\* 5);
	ps->capacity = 5;
	ps->top = 0;
}

栈顶指针:ps->top,初始化设置ps->top=0,指向栈顶元素的上层存储单元。

2.2 检查栈满
void CheckCapacity(Stack\* ps)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		SDataType\* arr = (SDataType\*)realloc(ps->array, sizeof(SDataType)\* (ps->capacity)\*2);
		if (arr == NULL)
		{
			return;
		}
		ps->array = arr;
		ps->capacity \*= 2;
	}
}

栈满条件为ps->top == ps->capacity,若空间已满,就进行2倍扩容。

2.3 入栈:尾插
void StackPush(Stack\* ps, SDataType data)
{
	assert(ps);
	CheckCapacity(ps);
	ps->array[ps->top++] = data;
}

进栈操作:栈不满时,先将数据存储到top指针指向的存储空间,再将top指针加 1 ;栈满时先扩容,在插入元素。

2.4 出栈:尾删
void StackPop(Stack\* ps)
{
	assert(!StackEmpty(ps));
	ps->top--;
}

出栈操作:先对栈进行断言判断是否为空,非空时只需将top指针减 1 即可,因为下一次进栈直接会将已经出栈的元素覆盖掉。

2.5 获取栈顶元素
SDataType StackTop(Stack\* ps)
{
	assert(!StackEmpty(ps));
	return ps->array[ps->top - 1];
}

2.6 获取栈中有效元素的个数
int StackSize(Stack\* ps)
{
	assert(ps);
	return ps->top;
}

由于使用数组来实现,所以栈顶指针的数据和有效元素个数相等。

2.7 检测栈是否为空
int StackEmpty(Stack\* ps)
{
	assert(ps);
	return ps->top == 0;
}

2.8 销毁栈
void StackDestroy(Stack\* ps)
{
	assert(ps);
	free(ps->array);
	ps->capacity = 0;
	ps->top = 0;
	ps->array = NULL;
}

注意:这里的top指针指向栈顶元素的上层存储空间,所以进栈操作为ps->array[ps->top++] = data,出栈操作为ps->top--,。若栈顶指针初始化为ps->top=-1,即top指向栈顶元素,则入栈操作为ps->array[++ps->top]=data,出栈操作不变。栈空判断条件为ps->top==-1,栈满判断条件为++ps->top==ps->capacity

3. 源代码

3.1 stack.h
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
typedef int SDataType;


typedef struct Stack
{
	SDataType\* array;
	int capacity;
	int top;
}Stack;

void StackInit(Stack\* ps);

// 入栈:尾插
void StackPush(Stack\* ps, SDataType data);

// 出栈:尾删
void StackPop(Stack\* ps);

// 获取栈顶元素
SDataType StackTop(Stack\* ps);

// 获取栈中有效元素的个数
int StackSize(Stack\* ps);

// 检测栈是否为空
int StackEmpty(Stack\* ps);

// 销毁栈
void StackDestroy(Stack\* ps);

3.2 stack.c
#include "stack.h"



void StackInit(Stack\* ps)
{
	assert(ps);
	ps->array = (SDataType\*)malloc(sizeof(SDataType)\* 5);
	ps->capacity = 5;
	ps->top = 0;
}


void CheckCapacity(Stack\* ps)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		SDataType\* arr = (SDataType\*)realloc(ps->array, sizeof(SDataType)\* (ps->capacity)\*2);
		if (arr == NULL)
		{
			return;
		}
		ps->array = arr;
		ps->capacity \*= 2;
	}
}

// 入栈:尾插
void StackPush(Stack\* ps, SDataType data)
{
	assert(ps);
	CheckCapacity(ps);
	ps->array[ps->top++] = data;

}

// 出栈:尾删
void StackPop(Stack\* ps)
{
	assert(!StackEmpty(ps));
	ps->top--;
}

// 获取栈顶元素
SDataType StackTop(Stack\* ps)
{
	assert(!StackEmpty(ps));
	return ps->array[ps->top - 1];
}

// 获取栈中有效元素的个数
int StackSize(Stack\* ps)
{
	assert(ps);
	return ps->top;
}

// 检测栈是否为空
int StackEmpty(Stack\* ps)
{
	assert(ps);
	return ps->top == 0;
}

// 销毁栈
void StackDestroy(Stack\* ps)
{
	assert(ps);
	free(ps->array);
	ps->capacity = 0;
	ps->top = 0;
	ps->array = NULL;
}

void Print(Stack\* ps)
{
	assert(ps);
	int i = 0;
	while (i < ps->top)
	{
		printf("%d ", ps->array[i]);
		i++;
	}
	printf("\n");
}
void test()
{
	Stack ps;
	StackInit(&ps);
	StackPush(&ps, 0);
	StackPush(&ps, 1);
	StackPush(&ps, 2);
	StackPush(&ps, 3);
	StackPush(&ps, 4);
	StackPush(&ps, 5);
	Print(&ps);
	StackPop(&ps);
	Print(&ps);
	int ret = StackTop(&ps);
	printf("%d\n", ret);
	ret = StackSize(&ps);
	printf("%d\n", ret);
}

3.3 test.c
#include "stack.h"

int main()
{
	test();
	return 0;
}

二、队列

1.队列的基本概念

队列也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队;删除元素称为出队。
  队头:允许删除的一端,又称队首;
  队尾:允许插入的一端;
  空队列:不含任何元素的空表。

队列中的元素遵守后进先出FIFO(First In First Out)的原则。
在这里插入图片描述

2.队列的链式存储

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
  队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表。头指针指向队头结点,尾指针指向队尾结点,即单链表的最后一个结点。
在这里插入图片描述

队列的链式存储类型描述如下:
typedef int QDataType;
typedef struct QNode //队列的每个节点(链表)
{
	int data;
	struct QNode\* next;
}QNode;

typedef struct Queue //队列
{
	QNode\* front; //队头指针
	QNode\* rear; //队尾指针
	int size; //队列元素个数
}Queue;

2.1 队列初始化
void QueueInit(Queue\* q)
{
	assert(q);
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
}

2.2 入队
void QueuePush(Queue\* q, QDataType data)
{
	assert(q);
	QNode\* newNode = (QNode\*)malloc(sizeof(QNode)); //创建结点
	newNode->next = NULL;
	newNode->data = data;

	if (QueueEmpty(q)) //队列为空
	{
		q->front = newNode;
	}
	else //队列中已有元素
	{
		q->rear->next = newNode;
	}
	q->rear = newNode;
	q->size++;
}

2.3 出队
void QueuePop(Queue\* q)
{
	assert(q);
	assert(!QueueEmpty(q)); //断言:队列为空
	QNode\* delNode = q->front;
	if (q->front == q->rear) //队列中只有一个元素
	{
		q->front = q->rear = NULL;
	}
	else //队列有多个元素
	{
		q->front = delNode->next;
	}
	free(delNode);
	q->size--;
}

2.4 获取队头元素
QDataType QueueFront(Queue\* q)
{
	assert(q);
	assert(!QueueEmpty(q));
	return q->front->data;
}

2.5 获取队尾元素
QDataType QueueBack(Queue\* q)
{
	assert(q);
	assert(!QueueEmpty(q));
	return q->rear->data;
}


![img](https://img-blog.csdnimg.cn/img_convert/ea06ce88f85bf31d02d3d840baa97209.png)
![img](https://img-blog.csdnimg.cn/img_convert/f9999cd190c5884be1db062ba7b78206.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

	assert(!QueueEmpty(q));
	return q->front->data;
}

2.5 获取队尾元素
QDataType QueueBack(Queue\* q)
{
	assert(q);
	assert(!QueueEmpty(q));
	return q->rear->data;
}


[外链图片转存中...(img-TKdzaJd4-1715040032631)]
[外链图片转存中...(img-VSGMnJn9-1715040032631)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值