栈(stack)的定义:
栈是限定仅仅在表尾进行插入或删除操作的线性表。因此,进行插入或删除的这一端叫栈顶(top),相应的,另一端叫栈底。不含元素的空表称为空栈。
如下图:假设按照数字:1,2,3,4,5次序依次入栈,则数字1称为栈底元素,5称为栈顶元素,如果要退栈,数字5是第一个退出去的。因此,栈的修改是按照后进先出的原则进行的。
栈的特点:先进后出,后进先出

栈的基本操作:
1.进栈或压栈(插入)
2.出栈(删除)
3.判断是否为空表
4.遍历
栈的顺序结构实现:
#include<stdio.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int top;
}Stack;
//初始化
void initStack(Stack* s) {
s->top = -1;//压栈+1 为0,数组下标从0开始
}
栈的基本操作:
1.进栈或压栈(插入)
//栈的顺序结构-进栈/压栈
int push(Stack* s, ElemType e) {
//判断是否栈满
if (s->top >= MAXSIZE - 1) {
printf("满了\n");
return 0;
}
s->top++;
s->data[s->top] = e;
return 1;
}
2.出栈(删除)
//栈的顺序结构-出栈
ElemType pop(Stack* s, ElemType *e) {
//判断是否为空表
if (s->top == -1) {
printf("空表\n");
return 0;
}
* e = s->data[s->top];
s->top--;
return 1;
}
3.判断是否为空表
//栈的顺序结构-判断栈是否为空
int isEmpty(Stack* s) {
if (s->top == -1) {
printf("空的\n");
return 1;
}
else {
return 0;
}
}
4.获取栈顶元素
//栈的顺序结构-获取栈顶元素
int getTop(Stack* s, ElemType* e) {
//判断是否为空表
if (s->top == -1) {
printf("空表\n");
return 0;
}
*e = s->data[s->top];
return 1;
}
5.遍历
//遍历
void ProStack(Stack* s) {
int i = 0;
while (i <= s->top) {
printf("%d ", s->data[i]);
i++;
}
printf("\n");
}
实现:
//实现
int main() {
Stack s;
initStack(&s);
//入栈
push(&s, 10);
push(&s, 20);
push(&s, 30);
push(&s, 40);
push(&s, 50);
//遍历
ProStack(&s);//10 20 30 40 50
ElemType e;
//出栈
pop(&s, &e);
printf("%d\n", e);//50
//遍历
ProStack(&s);//10 20 30 40
//获取栈顶元素
getTop(&s, &e);
printf("%d", e);//40
}
栈的动态内存分配
格式:
#define MAXSIZE 100
typedef struct {
ElemType* data;
int top;
}Stack;
//初始化
Stack* initStack() {
Stack* s = (Stack*)malloc(sizeof(Stack));
s->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
s->top = -1;
return s;
}
其他代码与上面一样。
实现:
//实现
int main() {
Stack* s = initStack();
//入栈
push(s, 10);
push(s, 20);
push(s, 30);
push(s, 40);
push(s, 50);
ElemType e;
//出栈
pop(s, &e);
printf("%d\n", e);//50
//获取栈顶元素
getTop(s, &e);
printf("%d", e);//40
}
栈的链式结构实现
格式:
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct stack {
ElemType data;
struct stack* next;
}Stack;
//依然满足栈的特点:先进后出,后进先出
//如果使用头插法那么尾结点就是栈底,首结点后第一个元素就是栈顶
Stack* initStack() {
Stack* s = (Stack*)malloc(sizeof(Stack));
s->data = 0;
s->next = NULL;
return s;
}
操作:
1.判断是否为空
//判断栈是否为空
int isEmpty(Stack* s) {
if (s->next == NULL) {
printf("空的\n");
return 1;
}
else
{
return 0;
}
}
2.头插法进栈
//进栈(头插法)
int push(Stack* s, ElemType e) {
Stack* p = (Stack*)malloc(sizeof(Stack));
p->data = e;
p->next = s->next;
s->next = p;
return 1;
}
3.出栈
//出栈(删除头结点后一个结点的数据)
/*
思路:
找到头结点p
用指针q记录要出栈的结点
通过改变p的后继结点实现出栈
*/
int pop(Stack* s, ElemType* e) {
//判断是否为空
if (s->next == NULL) {
printf("空的!");
return 0;
}
*e = s->next->data;
Stack* q = s->next;
s->next = q->next;
free(q);
return 1;
}
4.获取栈顶元素
//获取栈顶元素
int getTop(Stack* s, ElemType* e) {
//判断是否为空
if (s->next == NULL) {
printf("空的!");
return 0;
}
*e = s->next->data;
return 1;
}
5.遍历
//遍历
void PriStack(Stack* s) {
Stack* q = s->next;//创建一个结构体类型的变量指向栈中的第一个元素
//通过循环遍历打印输出
while (q != NULL) {
printf("%d ", q->data);
q = q->next;
}
}
实现:
int main() {
Stack* s = initStack();//创建一个头结点
//进栈
push(s, 1);
push(s, 2);
push(s, 3);
push(s, 4);
push(s, 5);
//遍历
PriStack(s);//5 4 3 2 1
//出栈
ElemType e;
pop(s, &e);
printf("出栈元素为:%d\n", e);//出栈元素为:5
//遍历
PriStack(s);//4 3 2 1
//获取栈顶元素
printf("栈顶元素为:%d", getTop(s, e));//4
}

被折叠的 条评论
为什么被折叠?



