栈的特点:先进后出 后进先出
1、栈分成了栈顶和栈底(在栈顶进行元素的插入和删除)
2、入栈(push) 出栈(pop)
栈的顺序存储 (使用 数组)
数组的首地址做栈顶还是栈底比较好?
答:做栈底 比较好,因为 栈顶要进行元素的插入和删除操作,所以数组尾部更适合比较频繁的插入和删除
栈的结构体
typedefstructStack{
intdata[MAX]; //数据域
intsize; //栈的大小
}Stack,*SeqStack;
• 栈的初始化
SeqStackcreate(){
//创建栈,相当于 动态开辟一个数组出来
SeqStackp=(Stack*)malloc(sizeof(Stack));
if(p==NULL){
returnNULL;
}
//初始化 栈的大小
p->size=0;
//初始化 栈中的元素
for(inti=0;i<MAX;i++){
p->data[i]=0;
}
returnp;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6eb6413cb2c6cdf674592e325a4f4035.png)
入栈
voidpush(SeqStackstack,intdata){
if(stack===NULL){
return;
}
// 入栈 需要判断 栈是否已满
if(stack->size==MAX){
printf("栈已满!\n");
return;
}
//stack->size 栈的大小就是我们插入元素的下一个位置
stack->data[stack->size]=data;
//改变栈的大小
stack->size++;
}
入栈需要注意栈是否为空 栈是否已满
出栈
voidpop(SeqStackstack){
if(stack==NULL){
return;
}
if(stack->size==0){
printf("栈已空!\n");
return;
}
//删除一个元素
stack->data[stack->size-1]=0;
//改变栈的大小
stack->size--;
}
入栈 需要注意 栈是否 不存在,和 栈是否已空
栈的链式存储(链表)
链表的头结点做栈顶还是栈底?
答:栈顶 因为 链表的头结点端 可以 更方便的进行元素的 插入(头插法)和 删除(头结点做前驱)
栈链式存储结构体
//结点结构体
typedefstructNode{
intdata;
structNode*next;
}Node;
//栈的结构体
typedefstructStack{
structNodeheader; //头结点
intsize; //栈的大小 即元素个数
}Stack, *LinkStack;
• 初始化栈
LinkStackinit_LinkStack(){
// myStack 是指针,指向申请的空间
LinkStackmyStack=(Stack*)malloc(sizeof(Stack));
if(mystack==NULL){
returnNULL;
}
//初始化长度 为 0
myStack->size=0;
//相当于 初始化链表的头结点 指针域
myStack->header.next=NULL;
}
什么时候使用 -> 什么时候使用 . ?
-> 在指针的时候
. 在变量名的时候
注意事项
struct Node *list list->next list->next
struct Node a; a.data a.next
入栈
//入栈
voidpush_SeqStack(SeqStackstack, intdata)
{
//本质 --- 尾插
if ( stack==NULL)
{
return;
}
if (stack->size==MAX)
{
printf("栈已满\n");
return;
}
//尾插
stack->data[stack->size] =data;
//更新栈大小
stack->size++;
}
出栈
//出栈
voidpop_SeqStack(SeqStackstack)
{
//本质 --- 尾删
if (stack==NULL)
{
return;
}
if (stack->size==0)
{
printf("栈已空\n");
return;
}
stack->data[stack->size-1] =0;
//更新栈大小
stack->size--;
}