1.栈的定义和特点
1.栈的定义
1.限定仅在表尾进行插入和删除操作的线性表
2.允许插入和删除的一端称为栈顶,另一端称为栈底。
2.栈的特点
栈的示意图:
栈的操作特征:先进后出(后进先出)
栈的运算规则 :只能在栈顶运算,且访问结点时依照后进先出 (LIFO)的原则
栈的存储结构 :用顺序栈或链栈存储均可,但以顺序栈更常见
栈的实现方式 :关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的不同而不同
基本操作:有入栈、出栈、读栈顶元素值、建栈(初始化)、 判断栈满、栈空等(栈逻辑上不存在遍历)
2.栈的代码实现
1.顺序栈
1.结点结构
#define maxsize 10
///顺序栈///
/*typedef struct{
int date[maxsize];//栈中元素 固定内存
int top;// 栈顶指针
}sstack;*/
typedef struct{
int *date;//栈中元素 自由开内存
int top;// 栈顶指针
}sstack;
2.初始化
//初始化
sstack initstack()
{
sstack s;
s.date =(int*)malloc(sizeof(int)*maxsize);
s.top=-1;//初始化栈顶指针
//也有 s.top=0
// =-1,先加后赋值,指针指向栈顶元素
//=0,先赋值再加,指针指向 栈顶元素的下一个存储单元
return s;
}
3.入栈
//入栈--对栈进行了修改,指针传递
void Pushh(sstack *s,int k)
{
//栈空间固定,加入一个元素要先判断是否满了,还能不能加入
if(s->top==maxsize-1)
{
printf("栈满\n");//栈满报错,不能加入
}
else{
s->top++;
s->date [s->top]=k;
//s.date [++s.top]=k;
}
}//若top初始化为0,如何改写:将top++和赋值两行代码交换 //s.date[s.top++]=k
4.出栈
//出栈
void Popp(sstack *s)
{
//删除之前判空,还有没有的删
if(s->top==-1)
{
printf("栈空\n");//栈空报错,不能删除
}
else{
s->top--;
}
}//若top初始化为0,操作也要改变,这里不再赘述
5.读取栈顶元素
void gettop(sstack s)
{
int x;
//判空,还有没有的读取
if(s.top==-1)
{
printf("栈空\n");//栈空报错,不能删除
}
else{
x=s.date[s.top];
printf("%d\n",x);
}
} //若top初始化为0,操作将发生部分改变,这里不再赘述
2.链栈
1.结点结构
///链栈--单链表实现栈///
typedef struct listackNode{//链栈结点
int date;//链栈结点中元素
struct listackNode* next;//指针
}sstack,*listack;
//此处的listack与链表代码中的 linklist类似
//listack==sstack *;
//使用 listack 声明链栈中的结点指针,意在强调操作对象是栈;
//使用 sstack* 声明链栈中的结点指针,意在强调操作对象是栈中的某个结点
//链栈中无栈顶指针,如何实现在栈顶操作,实现先进后出
//直接在链表表头进行操作,链表表头相当于栈顶
//入栈:头插。 出栈:删除首元结点
2.初始化
//初始化
listack initstack()
{
listack s=(listack)malloc(sizeof(sstack));
s->next=NULL;
return s;
}
3.入栈
//入栈--对栈进行了修改,指针传递
void Pushh(listack s,int k)
{
//链表结点个数可以动态调整,无需判满
//头插法插入结点,实现入栈
sstack *p=(sstack*)malloc(sizeof(sstack));//p是待插入的新结点
p->date =k;
//头插法 插入p
p->next =s->next;
s->next =p;//有头结点
}
4.出栈
//出栈
void Popp(listack s)
{
//删除之前判空,还有没有的删
if(s->next==NULL)
{
printf("栈空\n");//栈空报错,不能删除
}
else
{
sstack *p=s->next ;//让p指向待删除的首元结点
s->next =p->next ;
free(p);
}
}
5.读取栈顶元素
//读取栈顶元素
void gettop(listack s)
{
int x;
//判空,还有没有的读取
if(s->next==NULL)
{
printf("栈空\n");//栈空报错,不能删除
}
else
{
x=s->next->date;
printf("%d\n",x);
}
}