一、栈
- 栈是先进后出的线性表,限定仅在表尾进行插入和删除操作的线性表,
- 把允许插入删除的一端称为栈顶。
- 栈的第一个数据元素称之为栈顶元素。
- 栈中不含任何数据元素称为空栈。
- 栈的插入操作称为进栈(push),也称压栈、入栈
- 栈的删除操作称为出栈(pop),也称弹栈,退栈
- 栈在计算机中主要有两种存储结构:顺序存储结构和链式存储结构,分别可以用数组和单链表来实现。
1.1、顺序栈
- 顺序栈是栈的顺序实现,即利用顺序存储结构实现的栈。顺序栈是指采用地址连续的存储空间(数组)依次存储栈中数据元素,由于入栈和出栈运算都是在栈顶进行,而栈底位置是固定不变的,可以将栈底位置设置在数组空间的起始处,栈顶位置是随入栈和出栈操作而变化的,故需用一个整型变量top来记录当前栈顶元素在数组中的位置。
typedef int data_t;
typedef struct {
data_t *data;
int maxlen;
int top;
}sqstack;
1.2、链表栈
- 链栈的实现思路同顺序栈类似,顺序栈是将数顺序表(数组)的一端作为栈底,另一端为栈顶;链栈也如此,通常我们将链表的头部作为栈顶,尾部作为栈底。
typedef int data_t;
typedef struct node {
data_t data;
struct node *next;
}listnode, *linkstack;
二、顺序栈的实现
2.1、顺序栈创建
sqstack * stack_create(int len) {
sqstack * s;
if ((s =(sqstack *)malloc(sizeof(sqstack))) == NULL) {
printf("malloc sqstack failed\n");
return NULL;
}
if ((s->data = (data_t *)malloc(len * sizeof(data_t)))==NULL) {
printf("malloc data failed\n");
free(s);
return NULL;
}
memset(s->data, 0, len*sizeof(data_t));
s->maxlen = len;
s->top = -1;
return s;
}
2.2、顺序栈入栈
int stack_push(sqstack * s, data_t value) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
if (s->top == s->maxlen-1) {
printf("stack is full\n");
return -1;
}
s->top++;
s->data[s->top] = value;
return 0;
}
2.3、顺序栈是否为空
int stack_empty(sqstack *s) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
return (s->top == -1 ? 1 : 0);
}
2.4、顺序栈是否满
int stack_full(sqstack *s) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
return (s->top == s->maxlen-1 ? 1 : 0);
}
2.5、顺序栈出栈
data_t stack_pop(sqstack *s) {
s->top--;
return (s->data[s->top+1]);
}
2.6 顺序栈顶元素
data_t stack_top(sqstack *s) {
return (s->data[s->top]);
}
2.7、顺序栈清空
int stack_clear(sqstack *s) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
s->top = -1;
return 0;
}
2.8、顺序栈释放
int stack_free(sqstack *s) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
if (s->data != NULL)
free(s->data);
free(s);
return 0;
}
三、链表栈的实现
3.1、链表栈创建
linkstack stack_create() {
linkstack s;
s = (linkstack)malloc(sizeof(listnode));
if (s == NULL) {
printf("malloc failed\n");
return NULL;
}
s->data = 0;
s->next = NULL;
return s;
}
3.2、链表栈入栈
int stack_push(linkstack s, data_t value) {
linkstack p;
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
p = (linkstack)malloc(sizeof(listnode));
if (p == NULL) {
printf("malloc failed\n");
return -1;
}
p->data = value;
p->next = s->next;
s->next = p;
return 0;
}
3.3、链表栈出栈
data_t stack_pop(linkstack s) {
linkstack p;
data_t t;
p = s->next;
s->next = p->next;
t = p->data;
free(p);
p =NULL;
return t;
}
3.4、链表栈是否空
int stack_empty(linkstack s) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
return (s->next == NULL ? 1 : 0);
}
3.5、链表栈栈顶元素
data_t stack_top(linkstack s) {
return (s->next->data);
}
3.6、链表释放
linkstack stack_free(linkstack s) {
linkstack p;
if (s == NULL) {
printf("s is NULL\n");
return NULL;
}
while (s != NULL) {
p = s;
s = s->next;
printf("free:%d\n", p->data);
free(p);
}
return NULL;
}