一.目录:
1.栈的认识和分类;
2.如何定义栈的结构体;
3.顺序栈的基本操作实现;
4.顺序栈的完整代码展示;
5.链式栈的实现;
二.栈的认识和分类:
栈,又称后进先出的线性表。你可以想象一下你的水杯,当你向你的水杯里倒水的时候,先进去的水在杯子底部,后进去的水在杯子上部。栈就是这样的一个模型。当你向栈里放入元素时,最先放进去的元素在栈的底部,后放进去的元素在栈的上部,出栈的时候,栈顶的元素先出,栈底的元素最后出。栈的表尾端有特殊含义,称为栈顶,相应地,表头端称为栈底。和线性表相似,线性表存在顺序表和链式表,栈表也存在链式和顺序结构。
三:定义栈的结构体:
typedef struct node
{
int *base;//栈底
int *top; //栈顶
int sizestract;//可存最大元素数量
}Sqstract;
当栈不存在时(建立前/销毁后),base为NULL,栈顶的初值等于栈底。
栈的顺序实现时,给base分配存储空间,但栈底不能动,只能指向栈底元素,所以不能通过base来对栈内元素进行操作。
top为栈顶指针,始终指向末尾元素的下一位,在栈不为空的情况下,*(top-1)为栈顶元素的值。
栈可以追加存储空间。
四.顺序栈的基本操作实现:
1.头文件及宏定义:
#include<stdio.h>
#include<stdlib.h>
#define MAX 10 //最大存储数量
#define up 10 //可以追加的存储数量
2.结构体定义;
typedef struct
{
int *base;//栈底
int *top;//栈顶
int sizestact;//栈可以存储的最大长度
}Sqstact;
3.栈的初始化:
void initstact(Sqstact *l)//栈的初始化
{
l->base=(int *)malloc(MAX*sizeof(int));
if(l->base==NULL)
printf("error\n");
l->top=l->base;
l->sizestact=MAX;
}
给base分配存储空间
4.入栈:
void push(Sqstact *l,int e)//入栈
{
//判断是否栈满
if(l->top-l->base>=l->sizestact)
{
l->base=(int *)realloc(l->base,(up+MAX)*sizeof(int));
l->sizestact+=up;
l->top=l->base+MAX;
}
*l->top=e;
l->top=l->top+1;
}
判断是否栈满,如果栈满,利用realloc函数重新分配其空间。注意判断栈满的条件,栈内的元素个数是否大于等于最大存储数量。
5.出栈:
void gettop(Sqstact *l)//出栈
{
if(l->base==l->top)
printf("栈空\n");
else
printf("%d",*(l->top-1));
l->top=l->top-1;
}
出栈之后,栈顶元素要移动一位。
6.求栈长:
void stactlength(Sqstact *l)//栈的长度
{
printf("%d\n",l->top-l->base);
}
7.主函数:
int main()
{
Sqstact *l;
initstact(l);
push(l,3);
push(l,2);
push(l,1);
stactlength(l);
gettop(l);
return 0;
}
检查函数是否能正常运行。
五:顺序栈的完整代码展示:
#include<stdio.h>
#include<stdlib.h>
#define MAX 10
#define up 10
typedef struct
{
int *base;//栈底
int *top;//栈顶
int sizestact;//栈可以存储的最大长度
}Sqstact;
void initstact(Sqstact *l)//栈的初始化
{
l->base=(int *)malloc(MAX*sizeof(int));
if(l->base==NULL)
printf("error\n");
l->top=l->base;
l->sizestact=MAX;
}
void push(Sqstact *l,int e)//入栈
{
//判断是否栈满
if(l->top-l->base>=l->sizestact)
{
l->base=(int *)realloc(l->base,(up+MAX)*sizeof(int));
l->sizestact+=up;
l->top=l->base+MAX;
}
*l->top=e;
l->top=l->top+1;
}
void gettop(Sqstact *l)//出栈
{
if(l->base==l->top)
printf("栈空\n");
else
printf("%d",*(l->top-1));
l->top=l->top-1;
}
void stactlength(Sqstact *l)//栈的长度
{
printf("%d\n",l->top-l->base);
}
int main()
{
Sqstact *l;
initstact(l);
push(l,3);
push(l,2);
push(l,1);
stactlength(l);
gettop(l);
return 0;
}
六:链式栈的实现:
链式栈可以理解为是尾进尾出的链表。
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
}Node;
//初始化栈表
Node *listcreat()
{
Node *list=(Node *)malloc(sizeof(Node));
list->next=NULL;
list->data=0;
return list;
}
//判断栈空
int isenpty(Node *list)
{
if(list->data==0||list->next==NULL)
{
return 1;
}
else
{
return 0;
}
}
//出栈
int intpop(Node *list)
{
if(isenpty(list))
return -1;
else{
Node *node=list->next;
list->next=node->next;
int data=node->data;
free(node);
list->data--;
return data;
}
}
//入栈
void push(Node *list)
{
Node *node=(Node *)malloc(sizeof(Node));
printf("请输入入栈数据\n");
scanf("%d",&node->data);
node->next=list->next;
list->next=node;
list->data++;
}
//遍历栈表
void print(Node *list)
{
Node *p=list;
while(p!=NULL)
{
printf("%d->",p->data);
p=p->next;
}
printf("NULL\n");
}
int main()
{
Node *list;
list=listcreat();
push(list);
push(list);
push(list);
print(list);
int data=intpop(list);
printf("current enem = %d\n",data);
print(list);
return 0;
}