目录
一、栈
1.概念与构成
栈是一种独特的线性表,只允许在一端进行插入和删除
进行插入删除的一端叫栈顶,另一端叫栈底
栈遵循先入后出(LIFO:Last In First Out)原则
插入叫入栈 / 压栈 / 进栈
删除叫出栈
2.创建动态栈
栈一般用数组实现最优,因为插入删除主要集中在尾部,用链表实现每次入栈还需要找尾
#pragma once #include <stdlib.h> #include <assert.h> #include <stdio.h> // 支持动态增长的栈 typedef int STDataType; typedef struct Stack { STDataType* a; int top; // 栈顶 int capacity; // 容量 }Stack; // 初始化栈 void StackInit(Stack* ps); // 入栈 void StackPush(Stack* ps, STDataType data); // 出栈 void StackPop(Stack* ps); // 获取栈顶元素 STDataType StackTop(Stack* ps); // 获取栈中有效元素个数 int StackSize(Stack* ps); // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 int StackEmpty(Stack* ps); // 销毁栈 void StackDestroy(Stack* ps);
3.栈初始化
void StackInit(Stack* ps)
{
assert(ps);
ps->a = NULL;
//ps->top = -1;//top指向插入数据
ps->top = 0;//top指向插入数据的后面
ps->capacity = 0;
}
不用二级指针的原因:这里改变的是结构体成员
4. 入栈
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if(ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* ret = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
if (ret == NULL)
{
perror("realloc fail");
return;
}
ps->a = ret;
ps->capacity = newcapacity;
}
ps->a[ps->top++] = data;
}
5.出栈
void StackPop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
6.获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top-1];
}
7.判断栈是否为空
int StackEmpty(Stack* ps)
{
assert(ps);
if (ps->top == 0)
{
return 1;
}
else
{
return 0;
}
}
8.获取栈内元素个数
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
9.销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
二、队列
1.概念与构成
队列是只允许在一端插入,另一端删除的特殊线性表
队列遵循先进先出(FIFO:First In First Out)原则
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
2.创建队列
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
// 链式结构:表示队列
typedef int QDataType;
typedef struct QListNode
{
struct QListNode* next;
QDataType data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* front;
QNode* rear;
QDataType 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);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
3.队列初始化
void QueueInit(Queue* q)
{
assert(q);
q->front = NULL;
q->rear = NULL;
q->size = 0;
}
4.插入(入队列)
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newNode = (QNode*)malloc(sizeof(QNode));
if(newNode == NULL)
{
perror("malloc fail");
return;
}
newNode->data = data;
newNode->next = NULL;
if (q->rear == NULL)
{
assert(q->front == NULL);
q->front = q->rear = newNode;
}
else
{
q->rear->next = newNode;
q->rear = newNode;
}
q->size++;
}
5.删除(出队列)
void QueuePop(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
if (q->front->next == NULL)
{
free(q->front);
q->front = q->rear = NULL;
}
else
{
QNode* next = q->_front->next;
free(q->front);
q->front = next;
}
q->size--;
}
6.获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
return q->front->data;
}
7.获取队列尾部元素
QDataType QueueBack(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
return q->rear->data;
}
8.获取队列有效元素个数
int QueueSize(Queue* q)
{
assert(q);
return q->size;
}
9.检测队列是否为空
int QueueEmpty(Queue* q)
{
assert(q);
return q->front == NULL && q->rear == NULL;
}
10.销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
QNode* cur = q->front;
while (cur)
{
QNode* next = q->front->next;
free(cur);
q->front = next;
}
q->front = q->rear = NULL;
q->size = 0;
}