1.上溢”:在栈已经存满数据元素的情况下,如果继续向栈内存入数据,栈存储就会出错。
2.“下溢”:在栈内为空的状态下,如果对栈继续进行取数据的操作,就会出错。
3.对于栈的两种表示方式来说,顺序栈两种情况都有可能发生;而链栈由于“随时需要,随时申请空间”的存储结构,不会出现“上溢”的情况。
4.顺序栈:顺序栈的实现采用的是数组。
在顺序栈中设定一个随时指向栈顶元素的变量(一般命名为 top ),当 top 的值为 -1 时,说明数组中没有数据,即栈中没有数据元素,为“空栈”;只要数据元素进栈,top 就加 1 ;数据元素出栈, top 就减 1 。
例如,使用顺序栈的存储结构将(’a’,’b’,’c’,’d’)四个元素逐个压栈并输出栈顶元素。
代码:
#include <stdio.h>
//元素elem进栈
int push(char *a, int top, char elem) {
a[++top] = elem;
return top;
}
//元素出栈
int pup(char *a, int top) {
if (top == -1) {
printf("空栈");
return -1;
}
printf("出栈元素:%c\n", a[top]);
top--;
return top;
}
int main() {
char a[100];
int top = -1;//空栈
//入栈
top = push(a, top, 'a');
top = push(a, top, 'b');
top = push(a, top, 'c');
top = push(a, top, 'd');
//出栈
top = pup(a, top);
top = pup(a, top);
top = pup(a, top);
top = pup(a, top);
top = pup(a, top);
return 0;
}
结果:
5.链栈:用线性表的链式存储结构实现。
链栈一般不需要创建头结点,头结点会增加程序的复杂性,只需要创建一个头指针就可以了。
用链表表示栈时,用链表头结点的一端作为栈的栈顶端,这样做的好处是当数据元素压栈或者弹栈时,直接使用头指针就可以完成,不需要增设额外的指针。
例如,用链栈实现将(’a’,’b’,’c’,’d’)四个数据元素压栈,再依次弹栈:
代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct lineStack {
char data;
struct lineStack *next;
}lineStack;//定义了一个结构体
//结构体元素入栈
lineStack *push(lineStack *stack, char a) {
lineStack *line = (lineStack *)malloc(sizeof(lineStack));
line->data = a;
line->next = stack;
stack = line;
return stack;
}
//结构体元素出栈
lineStack *pop(lineStack *stack) {
if (stack) {
lineStack *p = stack;
stack = stack->next;
printf("出栈元素:%c", p->data);
if (stack) {
printf("栈顶元素:%c\n", stack->data);
}
else
{
printf("栈已空\n");
}
free(p);
}
else
{
printf("栈内没有元素");
return stack;
}
return stack;
}
int main() {
lineStack * stack = NULL;
stack = push(stack, 'a');
stack = push(stack, 'b');
stack = push(stack, 'c');
stack = push(stack, 'd');
stack = pop(stack);
stack = pop(stack);
stack = pop(stack);
stack = pop(stack);
stack = pop(stack);
return 0;
}
结果: