线性表
线性表的特点:
1:有限,线性表的元素个数称为线性表的长度
2:有序,一个接着一个,除了首位外,每个元素有个前驱元素和一个后继元素,元素间是一对一的关系。
1.什么是栈
栈是限定仅在表尾进行插入和删除的线性表
栈就像是一摞盘子,每次洗碗时将盘子一个接着一个向上叠,使用时从上往下一个一个取,后放上去的在顶部,先使用,先放上去的在底部,后使用。
如上图:我们对栈的基本操作有进栈(压栈)和出栈.(弹栈)。
2.存储方式
栈有两种存储方式,一种是顺序存储,另一种是链式存储。
1 )顺序存储
:通过一维数组来实现。栈是要在表尾(栈顶)入栈出栈的,那么我们用数组的哪一端做栈底呢?
用下标为0的一端做栈底比较方便,因为栈顶要不断进行操作。
首先要设计一个结构体,它包含一个数组用来存数据,一个变量记录栈顶的位置。
#define MAXSIZE 100
typedef int SElemType;//栈的元素类型StackElementType
typedef struct {
SElemType a[MAXSIZE];
int top;
}sqstack;
//申请空间,将栈顶指针置为-1表栈空
sqstack A;
A.top=-1;
然后设计两个函数实现入栈,出栈操作
入栈 出栈操作
//入栈
int Push(sqstack *s,SElemType e){
if(s->top==MAXSIZE-1)//如果栈满了就返回-1
return -1;
s->top++; //如果没满就将将栈顶指针上移一位
s->a[s->top]=e;//将元素信息存入
return 1; //返回1表示成功入栈
}
//出栈,e用来存储栈顶元素
int Pop(sqstack *s,SElemType *e){
if(s->top==-1)//如果已经栈空返回-1
return -1;
*e=s->a[s->top--];//栈未空时将栈顶元素存入e中,栈顶指针下移
return 1;
}
优缺点
优点是代码简洁,操作简单,缺点是事先规定了栈大小,元素过少空间浪费,元素过多空间不够
2)链式存储
可以动态的申请空间,解决这个问题
我们用单链表来实现链栈
*思考一下:用链表的哪一头来做栈底,哪一头做栈顶呢?*
栈要在栈顶对数据入栈出栈,我们要考虑单链表每个节点指向下个节点,它无法访问上个节点,所以当一个元素出栈后,为了能找到栈里的元素,应该采用头插法实现入栈。
链栈需要的函数较多
链栈的函数
Stack *CreatStack();//创建
int PushStack(Stack *stack,DateType date);//入栈
int PopStack(Stack *stack);//出栈,把动态申请的空间给free了
DateType GetTopElement(Stack *stack);//获得栈顶元素
void DestoryStack(Stack *stack);//销毁
int IsEmpty(Stack *stack);//判断栈是否空了,类似上面top==-1
void StackEmpty(Stack