1.栈的基本概念
栈是一种逻辑结构,是一种特殊的线性表,特殊在只能在固定一端操作
只要满足上述条件,那么这种特殊的线性表就会呈现出一种"后进先出"的逻辑,这种逻辑就被称为栈,栈在生活中到处可见,比如堆叠的盘子、电梯中的人等等。
由于约定了只能在线性表固定的一端进行操作,于是给栈这种特殊的线性表的"插入"、"删除",另起了下面这些特殊的名称:
1. 栈顶 : 可以进行插入删除的一端
2. 栈底:栈顶的对端
3. 入栈: 将节点插入栈顶之上,也称为压栈,函数名通常为push()
4. 出栈:将节点从栈顶剔除,也称为弹栈,函数名通常额外pop()
5. 取栈顶: 取得栈顶元素,但不出栈,函数名通常为top()
基于这种固定一端操作的简单约定,栈获得了"后进先出"的基本特征
2.顺序栈
顺序存储意味着开辟一块连续的内存用于存储数据节点,一般而言,管理栈数据除了需要一块连续的内存之外,还需要记录栈的总容量、当前栈的元素个数、当前栈顶元素位置,如果有多线程还需要配合互斥锁和信号量等信息,为了方便管理,通常将这些信息统一于一个管理结构体中;
typedef int Elemtype;
// 描述顺序栈的类型
struct Seqstack
{
Elemtype *data; // 数据域 存储数据元素的值
int max_size; // 最大元素个数
int top; // 栈顶元素下标
//....
};
// 创建一个空的顺序栈
struct Seqstack *create_seqstack(struct Seqstack *stack, Elemtype max_size)
{
stack->data = (int *)malloc(sizeof(int) * max_size);
stack->top = -1;
stack->max_size = max_size;
}
struct Seqstack *create_seqstack_2(int size)
{
struct Seqstack *s = malloc(sizeof(*s));
if (s == NULL)
return NULL;
s->data = malloc(sizeof(Elemtype) * size);
if (s->data == NULL)
{
free(s);
return NULL;
}
s->max_size = size;
s->top = -1;
return s;
}
// 判断栈是否为空
bool Is_seqstack(struct Seqstack *stack)
{
if (stack->top == -1)
return false;
else
return true;
}
bool Is_seqstack_2(struct Seqstack *stack)
{
if (stack == NULL)
return false;
return stack->top == -1 ? true : false;
}
// 判断栈是否为满
bool Is_full(struct Seqstack *stack)
{
if (stack->top == stack->max_size - 1)
return false;
else
return true;
}
bool Is_full_2(struct Seqstack *stack)
{
if (stack == NULL)
return false;
return stack->top + 1 == stack->max_size ? true : false;
}
// 获取栈的长度
Elemtype Get_length(struct Seqstack stack)
{
return (stack.top - stack.data[0]);
}
Elemtype Get_length_2(struct Seqstack *stack)
{
if (stack == NULL)
return -1;
return stack->top + 1;
}
// 入栈
bool push_seqstack(struct Seqstack *stack, Elemtype x)
{
if (stack->top == -1)
return false;
// 入栈
stack->top += 1;
stack->data[stack->top] = x;
return true;
}
bool push_seqstack_2(struct Seqstack *stack, Elemtype x)
{
if (Is_full_2)
return false;
stack->data[stack->top++] = x;
return true;
}
// 出栈
bool pop_seqstack(struct Seqstack *stack, Elemtype *x)
{
if (stack->top == -1)
return false;
// 出栈
*x = stack->data[stack->top];
stack->top -= 1;
return true;
}
bool pop_seqstack_2(struct Seqstack *stack, Elemtype *x)
{
if (stack == NULL || Is_seqstack_2(stack))
return false;
if (x)
*x = stack->data[stack->top--];
return true;
}
// 获取栈顶元素
bool Get_pop_seqstack(struct Seqstack stack, int *x)
{
if (stack.top == -1)
return false;
// 获取
*x = stack.data[stack.top];
return true;
}
void Get_pop_seqstack_2(struct Seqstack *stack,Elemtype*d)
{
if(stack==NULL||Is_seqstack_2(stack))
return false;
if(d)
*d=stack->data[stack->top];
return true;
}
// 销毁栈
void Destroy_seqstaack(struct Seqstack *stack)
{
free(stack->data);
stack->data = NULL;
stack->max_size = 0;
stack->top = -1;
}
void Destroy_seqstaack_2(struct Seqstack *stack)
{
if (stack == NULL)
return;
if (stack->data)
free(stack->data);
stack->data = NULL;
free(stack);
}