一:栈
(1)概念
一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
(2)栈的操作示意图
1.1、2两个个数字的压栈过程
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
(3)进栈示意图
(4)栈的代码实现
#pragma once
#include"common.h"
//顺序栈
#define SEQ_STACK_DEFAULT_SIZE 8
#define SEQ_STACK_INC_SIZE 3
typedef struct SeqStack
{
ElemType* base;
size_t capacity;
int top;
}SeqStack;
///
//函数的接口地址
void SeqStackInit(SeqStack* pst);
bool SeqStackIsFull(SeqStack* pst);
bool SeqStackIsEmpty(SeqStack* pst);
void SeqStackPush(SeqStack* pst, ElemType x);
void SeqStackPop(SeqStack* pst);
void SeqStackPrint(SeqStack* pst);
ElemType SeqStackTop(SeqStack* pst);
void SeqStackDestroy(SeqStack* pst);
//
//函数的实现
void SeqStackInit(SeqStack* pst)
{
pst->base = (ElemType*)malloc(sizeof(ElemType) * SEQ_STACK_DEFAULT_SIZE);
assert(pst->base != NULL);
pst->capacity = SEQ_STACK_DEFAULT_SIZE;
pst->top = 0;
}
bool SeqStackIsFull(SeqStack* pst)
{
assert(pst != NULL);
return pst->top >= pst->capacity;
}
bool SeqStackIsEmpty(SeqStack* pst)
{
assert(pst != NULL);
return pst->top == 0;
}
void SeqStackPush(SeqStack* pst, ElemType x)
{
assert(pst != NULL);
if (SeqStackIsFull(pst))
{
printf("栈空间已满,%d不能入栈。\n", x);
return;
}
pst->base[pst->top++] = x;
}
void SeqStackPop(SeqStack* pst)
{
assert(pst != NULL);
if (SeqStackIsEmpty(pst))
{
printf("栈空间为空,不能进行出栈。\n");
return;
}
pst->top--;
}
void SeqStackPrint(SeqStack* pst)
{
assert(pst != NULL);
for (int i = pst->top - 1; i >= 0; --i)
{
printf("%d\n", pst->base[i]);
}
printf("\n");
}
ElemType SeqStackTop(SeqStack* pst)
{
assert(pst != NULL);
if (SeqStackIsEmpty(pst))
{
printf("栈已空,不能取栈顶元素.\n");
return;
}
return pst->base[pst->top - 1];
}
void SeqStackDestroy(SeqStack* pst)
{
assert(pst != NULL);
free(pst->base);
pst->base = NULL;
pst->capacity = pst->top = 0;
}
二:队列
(1)概念
只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特性。
入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一端称为队头。
(2)队列操作示意图
(3)队列代码的实现
#pragma once
#include "common.h"
/
//顺序队列
#define SEQ_QUEUE_DEFAULT_SIZE 8
typedef struct SeqQueue
{
ElemType* base;
int capacity;
int front;
int rear;
}SeqQueue;
///
//函数接口地址
void SeqQueueInit(SeqQueue* psq);
bool SeqQueueIsFull(SeqQueue* psq);
bool SeqQueueIsEmpty(SeqQueue* psq);
void SeqQueueEnque(SeqQueue* psq, ElemType x);
void SeqQueueDeque(SeqQueue* psq);
ElemType SeqQueueFront(SeqQueue* psq);
void SeqQueuePrint(SeqQueue* psq);
///
//函数的实现
void SeqQueueInit(SeqQueue* psq)
{
assert(psq != NULL);
psq->base = (ElemType*)malloc(sizeof(ElemType)*SEQ_QUEUE_DEFAULT_SIZE);
assert(psq->base != NULL);
psq->capacity = SEQ_QUEUE_DEFAULT_SIZE;
psq->front = psq->rear = 0;
}
bool SeqQueueIsFull(SeqQueue* psq)
{
assert(psq != NULL);
return psq->rear >= psq->capacity;
}
bool SeqQueueIsEmpty(SeqQueue* psq)
{
assert(psq != NULL);
return psq->front == psq->rear;
}
void SeqQueueEnque(SeqQueue* psq, ElemType x)
{
assert(psq != NULL);
if (SeqQueueIsFull(psq))
{
printf("队列已满,%d不能入队.\n");
return;
}
psq->base[psq->rear++] = x;
}
void SeqQueueDeque(SeqQueue* psq)
{
assert(psq != NULL);
if (SeqQueueIsEmpty(psq))
{
printf("队列已空,不能出队.\n");
return;
}
psq->front++;
}
ElemType SeqQueueFront(SeqQueue* psq)
{
assert(psq != NULL);
if (SeqQueueIsEmpty(psq))
{
printf("队列为空,不能取队头元素.\n");
return;
}
return psq->base[psq->front];
}
void SeqQueuePrint(SeqQueue* psq)
{
assert(psq != NULL);
for (int i = psq->front; i < psq->rear; ++i)
printf("%d ", psq->base[i]);
printf("\n");
}