1.特点
- 限制在一端进行插入与删除的线性表(俗称堆栈)
- 允许进行操作的一段称栈顶,另一端固定,成为栈底
- 栈中无元素成为空栈
- 先进先出(FIFO)
2.顺序栈
2.1顺序栈结构体组成
- 指针,指向栈顶;栈长度;栈顶数据下标
- 采用此种方法可在创建栈时候指定栈容量
- 结构图
typedef struct
{
datatype* data;//栈顶指针,指向保存数据的数组首地址
int maxlen;
int top;//栈顶数据下标
}seqstack;
2.2创建栈
- 按照上述结构体定义,应该先申请一个12字节内存用于保存指向栈的地址指针,栈容量,栈顶数据下标;再申请指定大小的数组,用于保存数据
- 初始化栈顶数据下标为-1,并指定栈大小
- 代码:
seqstack* stack_create(int len)
{
seqstack* s;
if ((s = (seqstack*)malloc(sizeof(seqstack))) == NULL)
{
printf("malloc failed\n");
return NULL;
}
if ((s->data = (datatype*)malloc(len * sizeof(datatype))) == NULL)
{
printf("malloc failed\n");
return NULL;
}
s->maxlen = len;
s->top = -1;
return s;
}
2.3判断栈是否为空
- 直接判断栈顶元素下标是否为-1即可,为-1代表空
- 代码:
int is_stack_empty(seqstack* s)
{
return(s->top == -1 ? 1 : 0);//空返回1,非空返回0
}
2.4判断栈是否为满
- 当栈顶下标为2时候代表栈内有3个元素,故可据此判断栈是否为满
- 代码:
int is_stack_full(seqstack* s)
{
return(s->top == s->maxlen - 1 ? 1 : 0);//满返回1
}
2.5清空栈
void stack_clear(seqstack* s)
{
s->top = -1;
}
2.6入栈
- 即向数组内添加数据
- 入栈前需判断栈是否满
- 之后插入数据,移动栈顶下标指针即可
- 代码:
int stack_push(seqstack* s, datatype value)
{
if (is_stack_full(s))
{
printf("stack is full\n");
return -1;
}
s->data[s->top + 1] = value;
s->top++;
return 1;
}
2.7出栈
- 出栈之前判断栈是否为空
- 将栈顶指针-1
- 取出数据
- 代码:
datatype stack_pop(seqstack* s)
{
if (is_stack_empty(s))
{
printf("stack is empty\n");
return -1;
}
s->top--;
return s->data[s->top + 1];/*返回出栈的元素*/
}
2.8取出栈顶数据
datatype stack_top(seqstack* s)
{
return (s->data[s->top]);
}
2.9销毁栈
- 注意需要free两次,因为之前申请了两次
- 将指针置空防止野指针
- 代码:
void stack_free(seqstack* s)
{
free(s->data);
s->data = NULL;
free(s);
s = NULL;
}
3.链式栈
3.1链式栈组成
typedef struct node
{
datatype data;
struct node* next;
}listnode;
3.2创建栈
listnode* linklist_stack_create()
{
listnode* s;
if ((s = (listnode*)malloc(sizeof(listnode))) == NULL)
{
printf("malloc failed\n");
return NULL;
}
s->data = -1;
s->next = NULL;
return s;
}
3.3判断栈是否为空
- 及直接判断其是否只含有头节点即可
- 链式栈基于链表,其空间大小可随时创建,只要有存储空间就可以一直增加,故不用判断是否栈满
- 代码:
int linklist_stack_is_empty(listnode* s)
{
return(s->next == NULL ? 1 : 0);
}
3.4入栈
int linklist_stack_push(listnode* s, datatype value)
{
listnode *p;
if ((p = (listnode*)malloc(sizeof(listnode))) == NULL)
{
printf("malloc failed\n");
return -1;
}
p->data = value;
p->next = s->next;
s->next = p;
return 0;
}
3.5出栈
- 即删除头节点的下一个节点
- 注意释放空间置空指针
- 代码
datatype linklist_stack_pop(listnode* s)
{
datatype ret;
listnode *p;
p = s->next;
ret = p->data;
s->next = p->next;
free(p);
p = NULL;
return ret;
}
3.6取栈顶数据
datatype linklist_stack_top(listnode* s)
{
return (s->next->data);
}
3.7清空栈
void linklist_stack_clear(listnode* s)
{
listnode* p;
p = s->next;
while (p)
{
s->next = p->next;
printf("%d is be delete\n", p->data);
free(p);
p = s->next;
}
p = NULL;
puts("");
}
3.8释放栈
void linklist_stack_free(listnode* s)
{
listnode* p;
p = s;
while (p)
{
s = s->next;
printf("%d is be delete\n", p->data);
free(p);
p = s;
}
puts("");
}