【数据结构】我家三岁表弟都明白的栈和队列,你不会不了解吧?

}


出栈操作:先对栈进行断言判断是否为空,非空时只需将`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)的原则。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f90db674b6784f709165e12728363a47.png)


### 2.队列的链式存储


  队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。  
   队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表。头指针指向队头结点,尾指针指向队尾结点,即单链表的最后一个结点。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/41e6470b6fcb47739c0709fb1a71e7a1.png)


#### 队列的链式存储类型描述如下:



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;
}


#### 2.6 获取队列中有效元素的个数



int QueueSize(Queue* q)
{
assert(q);
return q->size;
}


#### 2.7 检测队列是否为空



int QueueEmpty(Queue* q)
{
assert(q);
return q->rear == NULL;
}


#### 2.8 销毁队列



void QueueDestroy(Queue* q)
{
assert(q);
QNode* cur = q->front;
while (cur)
{
q->front = cur->next;
free(cur);
cur = q->front;
}

q->front = q->rear = NULL;
q->size = 0;

}


### 3. 源代码


#### 3.1 queue.h



#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <malloc.h>

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

typedef struct Queue
{
QNode* front;
QNode* rear;
int size;
}Queue;

void QueueInit(Queue* q);
void QueuePush(Queue* q, QDataType data);
void QueuePop(Queue* q);
QDataType QueueFront(Queue* q);
QDataType QueueBack(Queue* q);
int QueueSize(Queue* q);
int QueueEmpty(Queue* q);
void QueueDestroy(Queue* q);
void QueueTest();


#### 3.2 queue.c



#include “Queue.h”

void QueueInit(Queue* q)
{
assert(q);
q->front = NULL;
q->rear = NULL;
q->size = 0;
}
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++;

}
void QueuePop(Queue* q)

img
img
img

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

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

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

data;

if (QueueEmpty(q))
{
	q->front = newNode;
}
else
{
	q->rear->next = newNode;
}
q->rear = newNode;
q->size++;

}
void QueuePop(Queue* q)

[外链图片转存中…(img-lqnB4PaA-1714273605888)]
[外链图片转存中…(img-j9rHRmuo-1714273605889)]
[外链图片转存中…(img-rkI1BoMY-1714273605889)]

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值