1.栈
- 概念:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守先进后出原则。
- 入栈和出栈示意图
(1.)实现栈需要的接口
// 静态栈的结构
typedef int STDataType;
#define N 10
typedef struct Stack
{
STDataType _a[N];
int _top;
}Stack;
// 动态栈的结构
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;
int _capacity;
}Stack;
// 实现栈需要的接口
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;
int _capacity;
}Stack;
void StackInit(Stack* ps);// 栈的初始化
void StackDestory(Stack* ps);// 栈的销毁
void StackPush(Stack* ps, STDataType x);// 数据的压栈
void StackPop(Stack* ps);// 出栈
STDataType StackTop(Stack* ps);// 获取栈顶元素
bool StackEmpty(Stack* ps);// 判断栈是否为空
size_t StackSize(Stack* ps);// 获取栈的大小
// 栈接口的实现
void StackInit(Stack* ps)
{
// 栈的初始化
assert(ps);
ps->_a = NULL;
ps->_top = 0;
ps->_capacity = 0;
}
void StackDestory(Stack* ps)
{
// 栈的销毁
assert(ps);
ps->_a = NULL;
ps->_top = ps->_capacity = 0;
free(ps->_a);
ps = NULL;
}
void StackPush(Stack* ps, STDataType x)
{
// 数据的压栈
assert(ps);
if (ps->_top == ps->_capacity)
{
int newcapacity = (ps->_capacity == 0) ? 2 : (ps->_capacity * 2);
ps->_a = (STDataType*)realloc(ps->_a, newcapacity * sizeof(STDataType));
ps->_capacity = newcapacity;
}
ps->_a[ps->_top] = x;
++ps->_top;
}
void StackPop(Stack* ps)
{
// 出栈
assert(ps && ps->_top > 0);
--ps->_top;
}
STDataType StackTop(Stack* ps)
{
// 获取栈顶元素
assert(ps && ps->_top > 0);
return ps->_a[ps->_top - 1];
}
bool StackEmpty(Stack* ps)
{
// 判断栈是否为空
assert(ps);
return ps->_top == 0;
}
size_t StackSize(Stack* ps)
{
// 获取栈的大小
assert(ps);
return ps->_top;
}
2.队列
- 概念:只允许一端进行插入数据操作,在另一端进行删除操作的特殊线性表,队列具有先进先出的原则。
- 队尾:进行插入数据的操作。
- 队头:进行删除数据的操作。
- 队列可以用数组和链表的结构实现,但是用链表结构实现更优一些,因为如果使用数组结构,出队列在数组首部上出数据,效率会比较高。
- 入队和出队示意图
(1.)实现队列需要的接口
// 队列的结构
typedef int QUDataType;
// 队列结点的结构(链表)
typedef struct QueueNode
{
struct QueueNode* _next;
QUDataType _data;
}QueueNode;
typedef struct Queue
{
QueueNode* _front;// 队头
QueueNode* _rear;// 队尾
}Queue;
// 实现队列需要的接口
void QueueInit(Queue* pq);// 队列的初始化
void QueueDestory(Queue* pq);// 队列的销毁
QueueNode* BuyQueueNode(QUDataType x);// 创建一个新的结点
void QueuePush(Queue* pq, QUDataType x);// 入队(从队头入队)
void QueuePop(Queue* pq);// 出队(从队尾出队)
QUDataType QueueFront(Queue* pq);// 取队头元素
QUDataType QueueRear(Queue* pq);// 取队尾元素
bool QueueEmpty(Queue* pq);// 判断队列是否为空
int QueueSize(Queue* pq);// 获取队列的大小
(2.)队列接口的实现
// 队列接口的实现
void QueueInit(Queue* pq)
{
// 队列的初始化
assert(pq);
pq->_front = pq->_rear = NULL;
}
void QueueDestory(Queue* pq)
{
// 队列的销毁
assert(pq);
QueueNode* cur = pq->_front;
while (cur)
{
QueueNode* next = cur->_next;
free(cur);
cur = next;
}
pq->_front = pq->_rear = NULL;
}
QueueNode* BuyQueueNode(QUDataType x)
{
// 创建一个新的结点
QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));
node->_next = NULL;
node->_data = x;
return node;
}
void QueuePush(Queue* pq, QUDataType x)
{
// 入队(从队尾入队)
assert(pq);
QueueNode* node = BuyQueueNode(x);
if (pq->_rear == NULL)
{
pq->_front = pq->_rear = node;
}
else
{
pq->_rear->_next = node;
pq->_rear = node;
}
}
void QueuePop(Queue* pq)
{
// 出队(从队头出队)
assert(pq && pq->_front != NULL);
QueueNode* next = pq->_front->_next;
free(pq->_front);
pq->_front = next;
if (pq->_front == NULL)
pq->_rear = NULL;
}
QUDataType QueueFront(Queue* pq)
{
// 取队头元素
assert(pq && pq->_front != NULL);
return pq->_front->_data;
}
QUDataType QueueRear(Queue* pq)
{
// 取队尾元素
assert(pq && pq->_rear != NULL);
return pq->_rear->_data;
}
bool QueueEmpty(Queue* pq)
{
// 判断队列是否为空
assert(pq);
return pq->_front == NULL;
}
int QueueSize(Queue* pq)
{
// 获取队列的大小
assert(pq);
QueueNode* cur = pq->_front;
size_t size = 0;
while (cur)
{
++size;
cur = cur->_next;
}
return size;
}
3.环形队列
-
环形队列就是一种循环队列,可以用数组实现。
-
循环队列判空的条件:Q.rear == Q.front
-
循环队列判满的条件:Q.rear + 1 == Q.front