一.栈的介绍。
1.栈的定义:
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out) 的原则。
- 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
- 出栈:栈的删除操作叫做出栈。出数据也在栈顶。
注意:栈的操作都在栈顶,不管进栈出栈都是在栈顶操作。
2.出栈和压栈结构示意图。
链式结构:
数组形式:
据图可知,二者操作都在top处进行。
3.栈的实现。
(1)栈的封装:栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
- 栈的管理:
typedef struct stack
{
DataType *base;//动态数组
size_t capacity;//栈的容量
size_t top;//寸的数据大小
}stack;
- 栈的操作:
void StackInit(stack* ps, size_t sz);//初始化
void StackPush(stack* ps, DataType x);//入栈
void StackPop(stack* ps);//出栈
DataType StackTop(stack* ps);//取栈顶元素
void StackShow(stack* ps);//打印栈内元素
void StackClear(stack* ps);//清除栈内元素
void StackDestroy(stack* ps);//撤销栈
- 栈个功能实现。
static bool StackIsFull(stack *pst)//判断栈是否满
{
return pst->top >= pst->capacity;
}
static bool StackIsEmpty(stack *pst)//判断栈空
{
return pst->top == 0;
}
void StackInit(stack* ps, size_t sz)//栈的初始化
{
ps->capacity = sz > DEFAULT_STACK_SIZE ? sz : DEFAULT_STACK_SIZE;
ps->base = (DataType*)malloc(sizeof(DataType)*(ps->capacity));
assert(ps->base != NULL);
ps->top = 0;
}
void StackPush(stack* ps, DataType x)//压栈操作
{
if (StackIsFull(ps))
{
printf("栈已满,不能入栈。\n");
return;
}
ps->base[ps->top] = x;
ps->top++;
}
void StackShow(stack* ps)//打印栈
{
int i = ps->top-1;
for (i = ps->top - 1; i >= 0; --i)
{
printf("%d\n", ps->base[i]);
}
printf("\n");
}
void StackPop(stack* ps)//出栈操作
{
if (StackIsEmpty(ps))
{
printf("栈已空,不能出栈。\n");
return;
}
ps->top--;
}
DataType StackTop(stack* ps)//取栈顶
{
if (StackIsEmpty(ps))
{
printf("栈已空,不能取栈顶。\n");
return 0;
}
return ps->base[ps->top - 1];
}
void StackClear(stack* ps)//清空栈
{
ps->top = 0;
}
void StackDestroy(stack* ps)//撤销栈
{
free(ps->base);
ps->base = NULL;
ps->capacity = ps->top = 0;
}
二.队列介绍。
1.队列定义。
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
- 入队列:进行插入操作的一端称为队尾
- 出队列:进行删除操作的一端称为队头
2.队列的实现。
- 队列的管理
typedef struct Queue
{
DataType *base;//数组
size_t front;//对头下标
size_t tail;//队尾下标
size_t capacity;//队列容量
}Queue;
- 队列的操作
void QueueInit(Queue* ps, size_t sz);//队列的初始化
void QueuePush(Queue* ps,DataType x);//入队
void QueueShow(Queue* ps);//打印队列
void QueuePop(Queue* ps);//出队
void QueueFront(Queue* ps);//取队头
- 队列功能的实现
static QueueIsFull(Queue* ps)//判断是否满
{
return ps->tail >= ps->capacity;
}
static QueueIsEampty(Queue* ps)//判断是否空
{
return ps->front == ps->tail;
}
void QueueInit(Queue* ps,size_t sz)//初始化队列
{
ps->capacity = sz > DEFAULT_QUEUE_SIZE ? sz : DEFAULT_QUEUE_SIZE;
ps->base = (DataType *)malloc(sizeof(DataType)*(ps->capacity));
assert(ps->base != NULL);
ps->front = ps->tail = 0;
}
void QueuePush(Queue* ps, DataType x)//入队
{
if (QueueIsFull(ps))
{
printf("队列已满,不能插入%d了。\n", x);
return;
}
ps->base[ps->tail] = x;
ps->tail++;
}
void QueueShow(Queue* ps)//打印队列
{
size_t i = ps->front;
for(i = ps->front; i < ps->tail; ++i)
{
printf("%d ", ps->base[i]);
}
printf("\n");
}
void QueuePop(Queue* ps)//出队
{
if (QueueIsEampty(ps))
{
printf("队列已空,不能出队。\n");
return;
}
ps->front++;
}
void QueueFront(Queue* ps)//取队头
{
if (QueueIsEampty(ps))
{
printf("队列已空,不能取对头元素。\n");
return;
}
return ps->base[ps->front];
}