栈
栈特点: 先进后出,后进先出 ,为线性表。
举例:有个杯子,往里面放大饼,先放进去的大饼,最后一个拿出来;
(1)只能在栈顶进行插入和删除的线性表叫栈(堆栈)
(2)规则
先进后出,后进先出
栈 : 栈顶和栈底
栈针:指向栈顶的指针(top),始终指向栈顶
top: 1. 有效元素的个数 2. top-1 就能代表栈顶的有效元素的下标
栈是一种思想 先进后出
你可以用数组实现栈的思想 ----- 顺序栈
顺序栈思想:就顺序表的尾巴插入(入栈),在顺序表的尾巴进行删除最后一个元素(出栈)
也可以用链表去实现栈的思想 ----- 链式栈
链式栈思想:在链表的头节点的下一个位置插入一个节点(入栈),删除头节点的下一个节点(出栈)
typedef struct node_t
{
int data;
struct node_t* next;
};
顺序栈和链式栈的区别是什么??
(1)顺序栈,存在栈满,链式栈 ,长度不固定
(2)顺序栈和链式栈的存储结构不一样
顺序栈:顺序存储结构
链式栈:链式存储结构
例题:
1.创建一个空的栈 === 创建一个空的顺序表
2.入栈 === 在顺序表的尾巴上插入一个数据 有效元素个数+1
3.出栈 === 删除顺序表的尾巴 尾巴里面的数据域返回 有效元素个数-1
4.判断栈是否为满 == 判断顺序表是否未满
5.判断栈是否为空 == 判断顺序表是否为空
6.获取栈顶元素 == 将顺序表的尾巴节点里面的数据域返回
7.清空栈 == 清空顺序表
main函数:
int main(int argc, const char *argv[])
{
seqstack_t* p = createEmptyStack();//创建一个空的栈,申请一个结构体空间大小
pushStack(p,10);
pushStack(p,20);
pushStack(p,30);
pushStack(p,40);
pushStack(p,50);
pushStack(p,60);//入栈失败,因为N是5,最多装5个数
//将栈内的所有元素出栈
while(!isEmptyStack(p))//只要栈不为空,就进入循环,执行出栈操作,当栈空的时候,循环结束
{
//将出栈的每个元素打印输出
printf("%d ",popStack(p));//入栈的顺序是10 20 30 40 50,出栈的顺序是 50 40 30 20 10
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct
{
int data[N];
int top;//栈针,top代表有效元素的个数,同时在使用的时候,top也当做下标来使用
}seqstack_t;
创建一个空的栈:
//1.创建一个空的栈
seqstack_t* createEmptyStack()
{
//申请一个结构体空间大小
seqstack_t* p = malloc(sizeof(seqstack_t));
if(p == NULL)
{
printf("createEmptyStack malloc failed!!\n");
return NULL;
}
p->top = 0;//空栈,有效元素个数为0
return p;
判断为满为空:
/2.判断栈是否为满,栈满 返回1,未满返回0
int isFullStack(seqstack_t* p)
{
return p->top == N ? 1 : 0;//有效元素个数 == 数组最大长度,栈满
}
//3.判断栈是否为空,栈空,返回1,未空返回0
int isEmptyStack(seqstack_t* p)
{
return p->top == 0 ? 1 : 0;//有效元素个数 == 0 栈空
}
入栈:
//4.入栈(本质就是在数组的尾巴,进行插入操作)
int pushStack(seqstack_t* p, int x)
{
//0.容错判断
if(isFullStack(p))//如果栈满结束
{
printf("isFullStack!!!\n");
return -1;
}
//1.入栈,用top来当做数组中的下标来使用
p->data[p->top] = x;
//2.有效元素个数+1
p->top++;
return 0;
}
出栈:
//5.出栈,将出栈元素的值返回(本质就是在数组尾巴,删除操作)
int popStack(seqstack_t* p)
{
//0.容错判断
if(isEmptyStack(p))
{
printf("isEmptyStack!!\n");
return -1;
}
//1.p->top--,有两个目的:1. 有效元素个数-1 2.得到出栈元素的下标
p->top--;
//2.有效元素个数-1之后,正好得到,出栈的最后一个有效元素的下标
return p->data[p->top];
}
清空和获取顶部元素:
//6.清空栈
void clearStack(seqstack_t* p)
{
p->top = 0;
}
//7.获取栈顶元素的值,并不是让栈顶元素删除,出栈
int getTopValue(seqstack_t* p)
{
if(isEmptyStack(p))
{
printf("isEmptyStack!!\n");
return -1;
}
return p->data[p->top-1];//将栈顶的元素返回值,p->top-1得到最后一个有效元素的下标
}
//showBinNum(p, 10)
void showBinNum(seqstack_t* p, int num)
{
//0 1 0 1
//求num的每一个二进制位入栈
//再全部出栈打印
}