1.栈
1.1概念与结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中元素遵循先进后出的原则。
**压栈:**栈的插入操作叫做进站/压栈/入栈,入数据在栈顶。
出栈: 栈的删除操作叫做出栈。出数据也在栈顶。
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
1.2栈的实现
stack.h
cpp
#pragma once
#include"stdio.h"
#include"stdio.h"
#include"assert.h"
#include<stdbool.h>
//定义栈的结构
typedef int STDataType;
typedef struct Stack
{
STDataType* arr;
int capacity; //栈的空间大小
int top; //栈顶
}ST;
//初始化
void STInit(ST* ps);
//释放空间
void STDestroy(ST* ps);
//栈顶---入数据、出数据
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);
//取栈顶元素
STDataType StackTop(ST* ps);
//栈是否为空
bool StackEmpty(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
1.初始栈
cpp
void STInit(ST* ps)
{
asssert(ps);
ps->arr = NULL;
ps->capacity = ps->top = 0;
}
2.销毁栈
cpp
void STDestroy(ST* ps)
{
assert(ps);
if (ps->arr)
free(ps->arr);
ps->arr = NULL;
ps->capacity = ps->top = 0;
}
3.入栈
cpp
void StackPush(ST* ps, STDataType x)
{
assert(ps);
//判断空间是否充足
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity = 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->capacity, newcapacity * sizeof(newcapacity));
if (tmp == NULL)
{
perror("realloc fail");
exit(1);
}
ps->arr = tmp;
ps->capacity = newcapacity;
}
ps->arr[ps->top] = x;
ps->top++;
}
4.判断栈是否为空
cpp
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
5.出栈
cpp
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
--ps->top;
}
6.取栈顶元素
cpp
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->arr[ps->top-1];
}
7.获取栈中有效元素个数
cpp
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
2.队列
2.1概念与结构
概念:只允许在一端进行插入数据操作,在另一端进行删除操作的特殊线性表,队列具有先进先出的原则。
**入队列:**进行插入操作的一端称为队尾。
**出队列:**进行删除操作的一端称为队头。
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
2.2队列的实现
queue.h
cpp
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//定义队列结构
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
QueueNode* phead;
QueueNode* ptail;
int size;//保存队列有效数据个数
}Queue;
//队列初始化
void QueueInit(Queue* pq);
// ⼊队列,队尾
void QueuePush(Queue* pq, QDataType x);
// 出队列,队头
void QueuePop(Queue* pq);
//队列判空
bool QueueEmpty(Queue* pq);
//取队头数据
QDataType QueueFront(Queue* pq);
//取队尾数据
QDataType QueueBack(Queue* pq);
//队列有效元素个数
int QueueSize(Queue* pq);
//销毁队列
void QueueDestroy(Queue* pq);
1.队列初始化
cpp
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
2.从队尾入队列
cpp
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->phead = NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = pq->ptail->next;
}
pq->size++;
}
3.队列判空
cpp
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL && pq->ptail == NULL;
}
4.从队头出队列
cpp
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->ptail == pq->phead)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
else
{
QueueNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
--pq->size;
}
5.取队头数据
cpp
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->phead->data;
}
6.取队尾数据
cpp
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->ptail->data;
}
7.队列有效元素个数
cpp
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
8.销毁队列
cpp
void QueueDestroy(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QueueNode* pcur = pq->phead;
while (pcur)
{
QueueNode* next = pcur->next;
free(pcur);
pcur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}