一、原理
1、栈的分类:顺序栈和链栈。(栈其实是一种特殊的线性表)
2、栈的操作:入栈和出栈。(实际上栈的操作都是在对栈顶操作)
3、入栈和出栈规则:先进后出。如图:元素进栈顺序为1、2、3,4依次进栈。要是出栈的话,元素4最先出栈,元素1最后出栈。
4、栈的应用
①浏览器 "回退" 功能的实现,底层使用的就是栈存储结构。当你关闭页面 A 时,浏览器会将页面 A 入栈;同样,当你关闭页面 B 时,浏览器也会将 B入栈。因此,当你执行回退操作时,才会首先看到的是页面 B,然后是页面 A,这是栈中数据依次出栈的效果。
②编译器检测代码括号匹配问题。
二、代码
1、顺序栈
#include <stdio.h>
int top = -1;
//元素elem进栈
int push(int* a, int top, int elem) {
top++;
printf("进出栈元素位置:%d\n", top);
a[top] = elem;
return top;
}
//数据元素出栈
int pop(int * a, int top) {
if (top == -1) {
printf("空栈");
return -1;
}
printf("弹出栈元素位置:%d\n", top);
top--;
return top;
}
int main() {
int a[100];
top = push(a, top, 1);
top = push(a, top, 2);
top = push(a, top, 3);
top = push(a, top, 4);
top = pop(a, top);
top = pop(a, top);
top = pop(a, top);
top = pop(a, top);
top = pop(a, top);
return 0;
}
2、链栈
/*
链栈一种特殊的链表,实际上就是一个只能采用头插法插入或删除数据的链表。
*/
#include <stdio.h>
#include <stdlib.h>
//链表中的节点结构
typedef struct lineStack {
int data;
struct lineStack * next;
}lineStack;
//stack为当前的链栈,a表示入栈元素
lineStack* push(lineStack * stack, int 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("出栈元素:%d ", p->data);
if (stack) {
printf("新栈顶元素:%d\n", stack->data);
}
else {
printf("栈已空\n");
}
free(p);
}
else {
printf("栈内没有元素");
return stack;
}
return stack;
}
int main() {
lineStack * stack = NULL;
stack = push(stack, 1);
stack = push(stack, 2);
stack = push(stack, 3);
stack = push(stack, 4);
stack = pop(stack);
stack = pop(stack);
stack = pop(stack);
stack = pop(stack);
stack = pop(stack);
return 0;
}