一、栈-20220611
1.栈的概念及结构
栈:一种特殊的线性表,只允许在固定的一端进行插入和删除数据元素。进行数据插入和删除的一端叫做栈顶,另一端称为栈底。栈中的数据元素遵守后进先出的原则
压栈:栈的插入操作叫做进栈/压栈/入栈
出栈:栈的删除操作叫做出栈
2.数据结构中的栈与内存中的栈的区别
数据结构中的栈:这是一种数据结构,属于数据结构科目
操作系统中的栈:这是内存划分的一个区域,用来函数调用时建立栈帧的
3.栈中的数据入栈和出栈顺序
入栈顺序:1 2 3 4
出栈顺序:4 3 2 1
4.栈的实现方法-数组栈(数组)
4.0栈的定义和包含的头文件
//数据结构的定义
typedef struct Stack
{
StackDataType* a;//存储数据的数组
int top;//栈顶数据的位置
int capacity;//栈中的容量
}Stack;
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
4.1栈的初始化
//栈的初始化
void StackInit(Stack* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
4.2打印栈中的元素
//打印栈中的元素
void StackPrint(Stack* ps)
{
assert(ps);
for (int i = 0; i < ps->top; i++)
{
printf("%d ", ps->a[i]);
}
printf("NULL\n");
}
4.3入栈
//入栈
void StackPush(Stack* ps, StackDataType x)
{
assert(ps);
//检查容量并扩容
if (ps->top == ps->capacity)
{
int newcapacity;
if (0 == ps->capacity)
newcapacity = 4;
else
newcapacity = ps->capacity * 2;
StackDataType* newa = (StackDataType*)realloc(ps->a,sizeof(StackDataType) * newcapacity);
assert(newa);
ps->a = newa;
ps->capacity = newcapacity;
}
//插入
ps->a[ps->top] = x;
ps->top++;
}
4.4出栈
//出栈
void StackPop(Stack* ps)
{
assert(ps);
if (0 == ps->top)
{
printf("栈内无数据,无法出栈\n");
}
else
{
ps->top--;
}
}
4.5获取栈顶元素
//获取栈顶元素
StackDataType StackTop(Stack* ps)
{
assert(ps);
assert(ps->top);
return ps->a[ps->top - 1];
}
4.6获取栈中有效元素个数
//获取栈中有效元素个数
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
4.7检测栈是否为空,若为空返回1,不为空,返回0
//检测栈是否为空,若为空,返回-1,不为空,返回0
int StackEmpty(Stack* ps)
{
assert(ps);
if (0 == ps->top)
return 1;
else
return 0;
}
4.8销毁栈
//销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->top = 0;
ps->capacity = 0;
}
二、队列-20220612_01
1.队列的概念及结构
队列:只允许在一端进行插入数据,在另一端进行删除数据操作
队尾:插入数据的一端
队头:删除数据的一端
2.队列中的数据入队列和出队列顺序
入队列顺序:1 2 3 4
出队列顺序:1 2 3 4
3.队列的是实现方法-链表队列
3.0队列节点的定义和包含的头文件
typedef int QueueDataType;
队列节点的定义
typedef struct QueueNode
{
QueueDataType data;
struct QueueNode* next;
}QueueNode;
队列结构体的定义
typedef struct Queue
{
QueueNode* front;
QueueNode* tail;
}Queue;
#include<stdio.h>
#include<stdlib.h>
包含malloc和realloc函数
#include<assert.h>
包含assert函数
assert(表达式),当表达式为0时,退出程序,报错
3.1队列初始化
//队列初始化
void QueueInit(Queue* sq)
{
assert(sq);
sq->front = NULL;
sq->tail = NULL;
}
3.2打印队列
//打印队列
void QueuePrint(Queue* sq)
{
assert(sq);
QueueNode* current = sq->front;
while (current)
{
QueueNode* next = current->next;
printf("%d->", current->data);
current = next;
}
printf("NULL\n");
}
3.3队尾入队列
//队尾入队列
void QueuePush(Queue* sq, QueueDataType x)
{
//检查传入的是否是空指针
assert(sq);
//创造一个队列节点
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
assert(newnode);
newnode->data = x;
newnode->next = NULL;
//看队列是否为空
if (QueueEmpty(sq))
{
sq->front = newnode;
sq->tail = newnode;
}
else
{
sq->tail->next = newnode;
sq->tail = sq->tail->next;
}
}
3.4队头出队列
//队头出队列
void QueuePop(Queue* sq)
{
assert(sq);
if (QueueEmpty(sq))
{
printf("队列为空,无法出队列\n");
}
else
{
//记录队头的节点
QueueNode* oldfront = sq->front;
sq->front = sq->front->next;
free(oldfront);
oldfront = NULL;
if (NULL == sq->front)
{
sq->tail = NULL;
}
}
}
3.5获取队列头部元素
// 获取队列头部元素
QueueDataType QueueFront(Queue* sq)
{
assert(sq);
assert(sq->front);
return sq->front->data;
}
3.6获取队列队尾元素
// 获取队列队尾元素
QueueDataType QueueTail(Queue* sq)
{
assert(sq);
assert(sq->tail);
return sq->tail->data;
}
3.7获取队列中有效元素个数
// 获取队列中有效元素个数
int QueueSize(Queue* sq)
{
assert(sq);
int size = 0;
QueueNode* current = sq->front;
while (current)
{
QueueNode* next = current->next;
size++;
current = next;
}
return size;
}
3.8检测队列是否为空,如果为空返回-1,如果非空返回0
// 检测队列是否为空,如果为空返回1,如果非空返回0
int QueueEmpty(Queue* sq)
{
assert(sq);
if (NULL == sq->front)
{
return 1;
}
else
{
return 0;
}
}
3.9销毁队列
// 销毁队列
void QueueDestroy(Queue* sq)
{
assert(sq);
QueueNode* current = sq->front;
while (current)
{
QueueNode* oldnode = current;
QueueNode* next = current->next;
free(oldnode);
current = next;
}
sq->front = NULL;
sq->tail = NULL;
}