一、栈
1、什么是栈?
栈是一种特殊的线性表 ,只允许在固定的一端进行元素的插入和删除操作,且称进行操作的那一段为栈顶,另一端称为栈底;
2、栈的基本操作
(1)压栈
栈的插入操作,插入的数据在栈顶
(2)出栈
栈的删除操作,出栈的数据也是栈顶数据
即先进先出;
3、栈的实现
栈一般利用数组或者链表实现,常用数组结构实现,因为尾插时的代价比小;
stack.h
// 顺序表的动态存储
#ifndef _Stack_H_
#define _Stack_H_
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Stack
{
StDataType* array; // 指向动态开辟的数组
size_t size; // 有效数据个数
size_t capicity; // 容量空间的大小
}Stack;
// 基本增删查改接口
void StackInit(Stack* psl, size_t capacity);
void StackDestory(Stack* psl);
void StackPush(Stack* psl, StDataType x);
void StackPop(Stack* psl);
StDataType StackTop(Stack* psl);
int StackIsEmpty(Stack* psl);
#endif //_Stack_H_
stack.c
#include "stack.h"
void StackInit(Stack* psl, size_t capicity)
{
assert(psl);
psl->capicity = capicity;
psl->array = (StDataType *)malloc(capicity * sizeof(StDataType));
assert(psl->array);
psl->size = 0;
}
void StackDestory(Stack* psl)
{
assert(psl);
if (psl->array)
{
free(psl->array);
psl->array = NULL;
psl->size = 0;
psl->capicity = 0;
}
}
//判断是否要扩容
void CheckCapacity(Stack* psl)
{
assert(psl);
if (psl->size == psl->capicity)
{
psl->capicity *= 2;
psl->array = (StDataType *)realloc(psl->array, psl->capicity * sizeof(StDataType));
}
}
//压栈
void StackPush(Stack* psl, StDataType x)
{
assert(psl);
CheckCapacity(psl);
psl->array[psl->size] = x;
psl->size++;
}
//出栈
void StackPop(Stack* psl)
{
assert(psl || psl->size);
psl->size--;
}
//栈顶元素
StDataType StackTop(Stack* psl)
{
if (StackIsEmpty(psl))
{
return (StDataType)0;
}
return psl->array[psl->size - 1];
}
//判空
int StackIsEmpty(Stack* psl)
{
return psl->size == 0;
}
二、队列
1、什么是队列?
队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出特性;
2、队列的基本操作
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
3、队列实现
queue.h
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include "BTree.h"
typedef BTNode * QuDataType;
typedef struct QueueNode
{
QuDataType _data;//数据
struct QueueNode* _next;//下一个结点的指针
}QueueNode;
typedef struct Queue {
QueueNode * _head;
QueueNode * _rear;
}Queue;
void QueueInit(Queue* plist);
void QueueDestory(Queue* plist);
void QueuePop(Queue* plist);
void QueuePush(Queue* plist, QuDataType x);
QuDataType QueueTop(Queue* plist);
int QueueIsEmpty(Queue* plist);
#endif //_QUEUE_H_
queue.c
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void QueueInit(Queue* plist)
{
assert(plist);
plist->_head = NULL;
plist->_rear = NULL;
}
void QueueDestory(Queue* plist)
{
QueueNode * tmp;
while (plist->_head)
{
tmp = plist->_head;
plist->_head = plist->_head->_next;
free(tmp);
}
}
void QueuePop(Queue* plist)//头部删除
{
assert(plist);
QueueNode * tmp;
if (plist->_head)
{
tmp = plist->_head;
plist->_head = plist->_head->_next;
free(tmp);
}
}
void QueuePush(Queue* plist, QuDataType x)//尾部插入
{
QueueNode * cur = (QueueNode *)malloc(sizeof(QueueNode));//申请一个新的结点
cur->_data = x;
cur->_next = NULL;
if (QueueIsEmpty(plist))//该队列为空
{
plist->_head = plist->_rear = cur;
return;
}
//队列不为空
plist->_rear->_next = cur;//将cur接在rear后
plist->_rear = cur;//在将其改为rear
}
int QueueIsEmpty(Queue* plist)//判空
{
return plist->_head == NULL;
}
QuDataType QueueTop(Queue* plist)//返回队首元素
{
if (QueueIsEmpty(plist))
{
return (QuDataType)0;
}
return plist->_head->_data;
}
4、环形队列
环形队列可以用数组实现也可以用循环链表实现;(可用于解决生产者消费者问题)
环形队列:https://github.com/Wilingpz/sunny/tree/master/deque%E5%AE%9E%E7%8E%B0