首先, 这里的栈并不是内存中用来存放数据的那个栈。
栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
1.性质:后进先出(LIFO)
2. 空栈:不含任何数据元素的栈;top=-1; 栈中有一个元素时,top=0。
3. 栈的操作:进栈,压栈,入栈:栈的插入操作;出栈,弹栈:栈的删除操作;
4. 栈的抽象数据类型: 插入和删除:push,pop 同线性表。 元素具有相同的类型,相邻元素具有前驱和后继的的关系。
5.栈的常见操作:
创建栈
销毁栈
清空栈
进栈
出栈
获取栈顶元素
获取栈的长度
6.栈的存储结构分为顺序存储结构(顺序栈)和链式存储结构(链栈)
顺序栈:即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。顺序存储中,我们通常用数组下标表示结点的位置,因此当top为0时,并不表示该栈为空,而表示含有一个结点;因此,在初始化的时候,将top = -1;
链栈 :栈顶放在单链表的头部;链栈是不需要头结点的;链栈不存在栈满的情况。
下面,我们主要使用链式结构来实现栈的常见操作:
头文件 LinkStack.h
#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
#define FAILURE 10000
#define SUCCESS 10001
typedef int ElemType;
typedef struct node
{
ElemType data;
struct node *next;
}Node;
typedef Node *LinkNode;
typedef struct stack
{
LinkNode top;
int count;
}Stack;
typedef Stack *LinkStack;
#endif
接口函数 LinkStack.h
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
/*初始化栈*/
int InitStack(LinkStack *S)
{
(*S) =(LinkStack)malloc(sizeof(Stack));
if(NULL == (*S))
{
return FAILURE;
}
(*S)->top =NULL;
(*S)->count = 0;
return SUCCESS;
}
/*进栈*/
int PushStack(LinkStack S, ElemType x)
{
LinkNode p =(LinkNode ) malloc(sizeof(Node)); //为插入的结点分配空间
if (NULL == p)
{
return FAILURE;
}
p->data = x; //把要插入的元素放入结点的数据域
p->next = S->top;
S->top = p;
S->count++;
return SUCCESS;
}
//计算栈长
int StackLength(LinkStack S)
{
return (S->count);
}
//获取栈顶
int GetTop(LinkStack S, ElemType *x)
{
if(NULL == S)
{
return FAILURE;
}
*x = S->top->data;
return SUCCESS;
}
//出栈
int PopStack(LinkStack *S, ElemType x)
{
if(NULL == (*S) || (*S)->top == NULL)
{
return FAILURE;
}
LinkNode p = (*S)->top;
(*S)->top = p->next;
x = p->data;
(*S)->count--;
free(p); //释放
return SUCCESS;
}
//清空栈
int ClearStack(LinkStack *S)
{
if(NULL == (*S))
{
return FAILURE;
}
while((*S)->top)
{
LinkNode p = (*S)->top;
(*S)->top = p->next;
(*S)->count--;
free(p);
}
return SUCCESS;
}
//销毁栈
int StackDestroy(LinkStack *S)
{
if((*S) == NULL)
{
return FAILURE;
}
free(*S);
*S = NULL;
return SUCCESS;
}
主函数 main.c
#include <stdio.h>
#include "LinkStack.h"
int main()
{
int ret, i;
LinkStack s;
ElemType e;
ret = InitStack(&s);
if(FAILURE == ret)
{
printf("Init Failure!\n");
}
else
{
printf("Init Success!\n");
}
printf("Length is %d\n",StackLength(s));
for(i = 0; i < 10; i++)
{
e = i;
ret = PushStack(s, e);
if(SUCCESS == ret)
{
printf("Push %d Success!\n",e);
}
else
{
printf("Push %d Failure!\n");
}
}
printf("Length is %d\n",StackLength(s));
ret = GetTop(s, &e);
if(FAILURE == ret)
{
printf("Get Top Failure!\n");
}
else
{
printf("Top Element is %d\n",e);
}
for(i = 0; i < 5; i++)
{
// e = i + 1;
ret = PopStack(&s, e);
if(SUCCESS == ret)
{
printf("Pop %d Success!\n", e);
}
else
{
printf("Pop %d Failure!\n", e);
}
}
printf("Length is %d\n",StackLength(s));
ret = ClearStack(&s);
if(FAILURE == ret)
{
printf("Clear Failure!\n");
}
else
{
printf("Clear Success!\n");
}
printf("Length is %d\n",StackLength(s));
ret = StackDestroy(&s);
if(FAILURE == ret)
{
printf("Destroy Failure!\n");
}
else
{
printf("Destroy Stack Success!\n");
}
return 0;
}