嘿嘿,家人们,今天咱们来详细剖析数据结构中的栈和队列,好啦,废话不多讲,开干!
栈:一种 特殊的线性 表,其只允许在固定的一端进行插入和删除元素操作, 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底 。 栈中的数据元素遵守后进先出 LIFO ( Last In First Out )的原则. 压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶 . 出栈:栈的删除操作叫做出栈。 出数据也在栈顶 .


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

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

#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数字,非空则为0
while(!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;
}

#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);#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;
}#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数字,非空则为0
while(!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;
}队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低.

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

#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);#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;
}#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们觉得博主讲的不错的话,请动动你们滴小手给博主点点赞,你们滴鼓励将成为博主源源不断滴动力,同时也欢迎大家来指正博主滴错误~