当前位置: 首页 > news >正文

深入了解栈与队列:从基础到应用

嘿嘿,家人们,今天咱们来详细剖析数据结构中的栈和队列,好啦,废话不多讲,开干!


1.:栈

1.1:栈的概念与结构

1.2:栈的实现

1.2.1:Stack.h

1.2.2:Stack.c

1.2.2.1:初始化与入栈与出栈与获取栈顶元素

1.2.2.2:获取元素个数与判断栈为空与销毁栈

1.2.3:Test.c

1.2.3.1:测试初始化与入栈与出栈与获取栈顶元素

1.2.3.2:测试获取元素个数与判断栈为空与销毁栈

1.3:栈的总代码

1.3.1:Stack.h

1.3.2:Stack.c

1.3.3:Test.c

2:队列

2.1:队列的概念与结构

2.2:队列的实现

2.2.1:Queue.h

2.2.2:Queue.c

2.2.2.1:初始化与入队列和出队列与获取队列元素个数

2.2.2.2:获取队头与队尾与判断队列为空与销毁队列

2.2.3:Test.c

2.2.3.1:测试初始化与入队列和出队列与获取队列元素个数

2.2.3.2:测试获取队头与队尾与判断队列为空与销毁队列

3:队列的总代码

3.1:Queue.h

3.2:Queue.c

3.3:Test.c


1.:栈

1.1:栈的概念与结构

栈:一种特殊的线性,其只允许在固定的一端进行插入和删除元素操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底栈中的数据元素遵守后进先出LIFOLast In First Out)的原则.
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶.
出栈:栈的删除操作叫做出栈。出数据也在栈顶.

1.2:栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小.

1.2.1:Stack.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int STDataType;typedef struct Stack
{STDataType* _arr;//指向栈顶int _top;//容量int _capacity;
}Stack;void StackInit(Stack* pst);
//入栈
void StackPush(Stack* pst, STDataType data);
// 出栈
void StackPop(Stack* pst);// 获取栈顶元素
STDataType StackTop(Stack* ps);// 获取栈中有效元素个数
int StackSize(Stack* pst);// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* pst);// 销毁栈
void StackDestroy(Stack* pst);

1.2.2:Stack.c

1.2.2.1:初始化与入栈与出栈与获取栈顶元素
#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"void StackInit(Stack* pst)
{assert(pst);pst->_arr = NULL;//指向栈顶,一开始没有元素pst->_top = -1;pst->_capacity = 0;
}void CheckCapacity(Stack * pst)
{assert(pst);if(pst->_top + 1 == pst->_capacity){int NewCapacity = pst->_capacity == 0 ? 4 : pst->_capacity * 2;//如果传了个空指针,就等价于malloc(NewCapacity *  sizeof(STDataType))STDataType * Tmp = (STDataType*)realloc(pst->_arr, NewCapacity *  sizeof(STDataType));if(Tmp == NULL){perror("realloc fail");exit;}pst->_arr = Tmp;pst->_capacity = NewCapacity;}
}void StackPush(Stack* pst, STDataType data)
{assert(pst);CheckCapacity(pst);//由于top指向的是栈顶,因此先++,在入栈pst->_top++;pst->_arr[pst->_top] = data;
}void StackPop(Stack* pst)
{assert(pst);//确保栈里面有元素assert(pst->_top >= 0);pst->_top--;
}// 获取栈顶元素
STDataType StackTop(Stack* pst)
{assert(pst);assert(pst->_top >= 0);return pst->_arr[pst->_top];
}
1.2.2.2:获取元素个数与判断栈为空与销毁栈
// 获取栈中有效元素个数
int StackSize(Stack* pst)
{assert(pst);//top指向的是栈顶,因此要 + 1,数组下标从0开始return pst->_top + 1;
}// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* pst)
{assert(pst);if (pst->_top == -1)return 1;return 0;}// 销毁栈
void StackDestroy(Stack* pst)
{assert(pst);free(pst->_arr);pst->_arr = NULL;pst->_top = -1;pst->_capacity = 0;
}

1.2.3:Test.c

1.2.3.1:测试初始化与入栈与出栈与获取栈顶元素
#include "Stack.h"void TestPushAndPop(Stack* pst)
{StackInit(pst);StackPush(pst,1);printf("%d\n", StackTop(pst));StackPush(pst,2);printf("%d\n", StackTop(pst));StackPush(pst,3);printf("%d\n", StackTop(pst));StackPush(pst,4);printf("%d\n", StackTop(pst));printf("--------------------------------\n");printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);
}int main()
{Stack pst;TestPushAndPop(&pst);return 0;
}

1.2.3.2:测试获取元素个数与判断栈为空与销毁栈
#include "Stack.h"void TestPushAndPop(Stack* pst)
{StackInit(pst);StackPush(pst,1);printf("%d\n", StackTop(pst));StackPush(pst,2);printf("%d\n", StackTop(pst));StackPush(pst,3);printf("%d\n", StackTop(pst));StackPush(pst,4);printf("%d\n", StackTop(pst));printf("--------------------------------\n");printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);
}void TestOther(Stack * pst)
{StackInit(pst);StackPush(pst, 1);StackPush(pst, 2);StackPush(pst, 3);StackPush(pst, 4);//为空返回非0数字,非空则为0while(!StackEmpty(pst)){printf("%d And Size == %d\n", StackTop(pst), StackSize(pst));StackPop(pst);}StackDestroy(pst);
}int main()
{Stack pst;/*TestPushAndPop(&pst);*/TestOther(&pst);return 0;
}

1.3:栈的总代码

1.3.1:Stack.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int STDataType;typedef struct Stack
{STDataType* _arr;//指向栈顶int _top;//容量int _capacity;
}Stack;void StackInit(Stack* pst);
//入栈
void StackPush(Stack* pst, STDataType data);
// 出栈
void StackPop(Stack* pst);// 获取栈顶元素
STDataType StackTop(Stack* ps);// 获取栈中有效元素个数
int StackSize(Stack* pst);// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* pst);// 销毁栈
void StackDestroy(Stack* pst);

1.3.2:Stack.c

#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"void StackInit(Stack* pst)
{assert(pst);pst->_arr = NULL;//指向栈顶,一开始没有元素pst->_top = -1;pst->_capacity = 0;
}void CheckCapacity(Stack* pst)
{assert(pst);if (pst->_top + 1 == pst->_capacity){int NewCapacity = pst->_capacity == 0 ? 4 : pst->_capacity * 2;//如果传了个空指针,就等价于malloc(NewCapacity *  sizeof(STDataType))STDataType* Tmp = (STDataType*)realloc(pst->_arr, NewCapacity * sizeof(STDataType));if (Tmp == NULL){perror("realloc fail");exit;}pst->_arr = Tmp;pst->_capacity = NewCapacity;}
}void StackPush(Stack* pst, STDataType data)
{assert(pst);CheckCapacity(pst);//由于top指向的是栈顶,因此先++,在入栈pst->_top++;pst->_arr[pst->_top] = data;
}void StackPop(Stack* pst)
{assert(pst);//确保栈里面有元素assert(pst->_top >= 0);pst->_top--;
}// 获取栈顶元素
STDataType StackTop(Stack* pst)
{assert(pst);assert(pst->_top >= 0);return pst->_arr[pst->_top];
}// 获取栈中有效元素个数
int StackSize(Stack* pst)
{assert(pst);//top指向的是栈顶,因此要 + 1,数组下标从0开始return pst->_top + 1;
}// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* pst)
{assert(pst);if (pst->_top == -1)return 1;return 0;}// 销毁栈
void StackDestroy(Stack* pst)
{assert(pst);free(pst->_arr);pst->_arr = NULL;pst->_top = -1;pst->_capacity = 0;
}

1.3.3:Test.c

#include "Stack.h"void TestPushAndPop(Stack* pst)
{StackInit(pst);StackPush(pst,1);printf("%d\n", StackTop(pst));StackPush(pst,2);printf("%d\n", StackTop(pst));StackPush(pst,3);printf("%d\n", StackTop(pst));StackPush(pst,4);printf("%d\n", StackTop(pst));printf("--------------------------------\n");printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);printf("%d\n", StackTop(pst));StackPop(pst);
}void TestOther(Stack * pst)
{StackInit(pst);StackPush(pst, 1);StackPush(pst, 2);StackPush(pst, 3);StackPush(pst, 4);//为空返回非0数字,非空则为0while(!StackEmpty(pst)){printf("%d And Size == %d\n", StackTop(pst), StackSize(pst));StackPop(pst);}StackDestroy(pst);
}int main()
{Stack pst;/*TestPushAndPop(&pst);*/TestOther(&pst);return 0;
}

2:队列

2.1:队列的概念与结构

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低.

2.2:队列的实现

2.2.1:Queue.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QListDataType;//队列的节点
typedef struct QueueNode
{QListDataType _Value;struct QueueNode* _Next;
}QNode;typedef struct Queue
{//队头QNode* _Front;//队尾QNode* _Tail;int _size;
}Queue;// 初始化队列
void QueueInit(Queue* q);// 队尾入队列
void QueuePush(Queue* q, QListDataType data);// 队头出队列
void QueuePop(Queue* q);// 获取队列头部元素
QListDataType QueueFront(Queue* q);// 获取队列队尾元素
QListDataType QueueBack(Queue* q);// 获取队列中有效元素个数
int QueueSize(Queue* q);// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);// 销毁队列
void QueueDestroy(Queue* q);

2.2.2:Queue.c

2.2.2.1:初始化与入队列和出队列与获取队列元素个数
#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"// 初始化队列
void QueueInit(Queue* q)
{assert(q);q->_Front = NULL;q->_Tail = NULL;q->_size = 0;
}// 队尾入队列
void QueuePush(Queue* q, QListDataType Value)
{assert(q);QNode* NewNode = (QNode*)malloc(sizeof(QNode));if (NewNode == NULL){perror("malloc fail");exit(-1);}NewNode->_Next = NULL;NewNode->_Value = Value;//队头和队尾指向一致时if (q->_Front == NULL){q->_Front = NewNode;q->_Tail = NewNode;}else{//链接新节点q->_Tail->_Next = NewNode;//队尾指向新节点q->_Tail = NewNode;}q->_size++;
}// 队头出队列
void QueuePop(Queue* q)
{assert(q);assert(q->_Front && q->_Tail);if(q->_Front == q->_Tail){free(q->_Front);q->_Front = q->_Tail = NULL;}else{//保留下一个节点QNode* Temp = q->_Front->_Next;//释放旧节点free(q->_Front);//指向新节点q->_Front = Temp;}q->_size--;
}// 获取队列中有效元素个数
int QueueSize(Queue* q)
{return q->_size;
}
2.2.2.2:获取队头与队尾与判断队列为空与销毁队列
#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"// 获取队列中有效元素个数
int QueueSize(Queue* q)
{return q->_size;
}// 获取队列头部元素
QListDataType QueueFront(Queue* q)
{assert(q && q->_Front);return q->_Front->_Value;
}// 获取队列队尾元素
QListDataType QueueBack(Queue* q)
{assert(q && q->_Tail);return q->_Tail->_Value;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{return q->_size == 0 ? true : false;
}// 销毁队列
void QueueDestroy(Queue* q)
{QNode* Current = q->_Front;while (Current != NULL){//保留下一个节点QNode* Temp = Current->_Next;free(Current);Current = Temp;}q->_Front = NULL;q->_Tail = NULL;q->_size = 0;}

2.2.3:Test.c

2.2.3.1:测试初始化与入队列和出队列与获取队列元素个数
#include "Queue.h"void TestPushAndPop(Queue * q)
{QueueInit(q);QueuePush(q, 2);QueuePush(q, 3);QueuePush(q, 4);QueuePush(q, 5);printf("size == %d\n", QueueSize(q));QueuePop(q);QueuePop(q);QueuePop(q);QueuePop(q);printf("size == %d\n", QueueSize(q));
}int main()
{Queue q;TestPushAndPop(&q);return 0;
}

2.2.3.2:测试获取队头与队尾与判断队列为空与销毁队列
#include "Queue.h"void TestOther(Queue* q)
{QueueInit(q);QueuePush(q, 2);QueuePush(q, 3);QueuePush(q, 4);QueuePush(q, 5);printf("size == %d And Front == %d And Tail == %d\n", QueueSize(q),QueueFront(q),QueueBack(q));QueuePop(q);printf("size == %d And Front == %d And Tail == %d\n", QueueSize(q), QueueFront(q), QueueBack(q));QueuePop(q);printf("size == %d And Front == %d And Tail == %d\n", QueueSize(q), QueueFront(q), QueueBack(q));QueueDestroy(q);
}int main()
{Queue q;TestOther(&q);return 0;
}

3:队列的总代码

3.1:Queue.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QListDataType;//队列的节点
typedef struct QueueNode
{QListDataType _Value;struct QueueNode* _Next;
}QNode;typedef struct Queue
{//队头QNode* _Front;//队尾QNode* _Tail;int _size;
}Queue;// 初始化队列
void QueueInit(Queue* q);// 队尾入队列
void QueuePush(Queue* q, QListDataType data);// 队头出队列
void QueuePop(Queue* q);// 获取队列头部元素
QListDataType QueueFront(Queue* q);// 获取队列队尾元素
QListDataType QueueBack(Queue* q);// 获取队列中有效元素个数
int QueueSize(Queue* q);// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);// 销毁队列
void QueueDestroy(Queue* q);

3.2:Queue.c

#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"// 初始化队列
void QueueInit(Queue* q)
{assert(q);q->_Front = NULL;q->_Tail = NULL;q->_size = 0;
}// 队尾入队列
void QueuePush(Queue* q, QListDataType Value)
{assert(q);QNode* NewNode = (QNode*)malloc(sizeof(QNode));if (NewNode == NULL){perror("malloc fail");exit(-1);}NewNode->_Next = NULL;NewNode->_Value = Value;//队头和队尾指向一致时if (q->_Front == NULL){q->_Front = NewNode;q->_Tail = NewNode;}else{//链接新节点q->_Tail->_Next = NewNode;//队尾指向新节点q->_Tail = NewNode;}q->_size++;
}// 队头出队列
void QueuePop(Queue* q)
{assert(q);assert(q->_Front && q->_Tail);if(q->_Front == q->_Tail){free(q->_Front);q->_Front = q->_Tail = NULL;}else{//保留下一个节点QNode* Temp = q->_Front->_Next;//释放旧节点free(q->_Front);//指向新节点q->_Front = Temp;}q->_size--;
}// 获取队列中有效元素个数
int QueueSize(Queue* q)
{return q->_size;
}// 获取队列头部元素
QListDataType QueueFront(Queue* q)
{assert(q && q->_Front);return q->_Front->_Value;
}// 获取队列队尾元素
QListDataType QueueBack(Queue* q)
{assert(q && q->_Tail);return q->_Tail->_Value;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{return q->_size == 0 ? true : false;
}// 销毁队列
void QueueDestroy(Queue* q)
{QNode* Current = q->_Front;while (Current != NULL){//保留下一个节点QNode* Temp = Current->_Next;free(Current);Current = Temp;}q->_Front = NULL;q->_Tail = NULL;q->_size = 0;}

3.3:Test.c

#include "Queue.h"void TestPushAndPop(Queue * q)
{QueueInit(q);QueuePush(q, 2);QueuePush(q, 3);QueuePush(q, 4);QueuePush(q, 5);printf("size == %d\n", QueueSize(q));QueuePop(q);QueuePop(q);QueuePop(q);QueuePop(q);
}void TestOther(Queue* q)
{QueueInit(q);QueuePush(q, 2);QueuePush(q, 3);QueuePush(q, 4);QueuePush(q, 5);printf("size == %d And Front == %d And Tail == %d\n", QueueSize(q),QueueFront(q),QueueBack(q));QueuePop(q);printf("size == %d And Front == %d And Tail == %d\n", QueueSize(q), QueueFront(q), QueueBack(q));QueuePop(q);printf("size == %d And Front == %d And Tail == %d\n", QueueSize(q), QueueFront(q), QueueBack(q));QueueDestroy(q);
}int main()
{Queue q;//TestPushAndPop(&q);TestOther(&q);return 0;
}

好啦,uu们,栈和队列的这部分滴详细内容博主就讲到这里啦,如果uu们觉得博主讲的不错的话,请动动你们滴小手给博主点点赞,你们滴鼓励将成为博主源源不断滴动力,同时也欢迎大家来指正博主滴错误~

http://www.dtcms.com/a/562273.html

相关文章:

  • 做百度还是阿里网站好免费建立手机网站吗
  • [DeepOCR] 图像预处理单元 | OCRProcessor | init 核心标记化方法
  • 幼教资源网网站开发策划书wordpress 安装轮播
  • Paxos协议流程
  • 【合新通信】浸没式液冷与冷板式液冷未来前景对比
  • 数据结构刷题 ——001
  • 网站收录查询方法阿里云搭建多个网站
  • 上海快速建站wordpress菜单栏菜单简介
  • ps做阿里网站分辨率设置龙岩网页定制
  • 傻瓜式网站建设软件网络整合营销4i原则
  • 长春火车站属于哪个区设计制作一个网站
  • 建设个读书网站大约需要投入多少钱少儿编程线下培训机构排名前十
  • 做我女朋友的套路网站网站制作视频教程
  • 上饶市住房和城乡建设网站背景图网站
  • 福田企业网站优化方案免费有限公司网站
  • 有没有网站可以学做床上用品大连城市建设管理局网站
  • 无代码网站wordpress主题模板文件下载
  • 从搭建到打磨:我的纯前端个人博客开发复盘
  • 哪里有网站制作c 网站建设报告
  • 安徽省工程建设工程信息网站黔南seo
  • 网站外包建设dw做网站学习解析
  • JavaScript基础篇:Array常用方法
  • asp网站 换模板网站如何做快捷支付接口
  • 网站建设文章官网图片站手机网站怎么做
  • HTTP 协议基本格式与 Fiddler 抓包工具实战指南
  • 金仓数据库KingbaseES通过KDTS实现SQLServer至KingbaseES迁移深度实战指南
  • 做英语quiz的网站wordpress个人资料页修改
  • (论文速读)FDConv:用于密集图像预测的频率动态卷积
  • 网站定位案例wordpress默认域名
  • 句容网站建设制作郑州市建设局官方网站