定义
栈是只允许在一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
操作有:init push pop top isEmpty isFull clear getLength
定义
const int N=100;
typedef struct{
int data[N];
int top;// 初始为-1,始终指向当前栈顶元素,注意与指向下一个元素的写法有区别,
}stack;
stack* init()
{
stack *s=(stack*)malloc(sizeof(stack));
s->top=-1;
return s;
}
bool isFull(stack *s)
{
if(s->top==N-1)
return true;
return false;
}
bool isEmpty(stack *s)
{
if(s->top<0)return true;
return false;
}
void push(int n,stack *s)
{
if(isFull(s)){
cout<<"out of memory"<<endl;
return;
}
else{
s->top++;
s->data[s->top]=n;
}
}
int pop(stack *s)
{
if(isEmpty(s)){
cout<<"stack empty"<<endl;
return -1;
}else{
int temp=s->data[s->top];
s->top--;
return temp;
}
}
int top(stack *s)
{
if(isEmpty(s)){
cout<<"stack empty"<<endl;
return -1;
}else{
int temp=s->data[s->top];
return temp;
}
}
void clear(stack *s)
{
s->top=-1;
}
int getLength(stack * s)
{
return s->top+1;
}
/*****************************************/
链表构造栈的方法
typedef struct{
int data;
node* next;
}node;
typedef struct{
node* top;
}stack;
stack* init()
{
stack *s=(stack*)malloc(sizeof(stack));
s->top=null;
}
bool isFull(stack *s)
{
// 不需要判断,链表满只可能内存不足了
}
bool isEmpty(stack *s)
{
if(s->top==null)
return true;
return false;
}
void push(int n,stack *s)
{
node* p=(node*)malloc(sizeof(node));
p->data=n;
p->next=s->top;
s->top=p;
}
int pop(stack* s)
{
if(isEmpty(s))
{
cout<<"stack empty"<<endl;
return -1;
}else{
node* p=s->top;
int n=p->data;
s->top=s->top->next;
free(p);
return n;
}
}
int top(stack* s)
{
if(isEmpty(s))
{
cout<<"stack empty"<<endl;
return -1;
}else{
return s->top->data;
}
}
void clear(stack* s)
{
node* p;
while(s->top){
p=s->top;
s->top=s->top->next;
free(p);
}
}
int getLength(stack* s)
{
int n=0;
while(s->top){
n++;
s->top=s->top->next;
}
return n;
}
顺序栈
链栈
问题
栈的压入和弹出序列:给出两个序列,根据压入序列,判断弹出序列是否合理
两个栈共享同一数组:有两个栈s1和s2共享存储空间c[1..MaxSize],其中一个栈底设在c[1]处,另一个栈底设在c[MaxSize]处,分别编写s1和s2的进栈push(i,x)、退栈pop(i)和设置栈空setnull(i)的函数,其中i=1,2。注意:仅当整个空间c[1..MaxSize]占满时才产生上溢。
使用1个数组实现3个栈。当且仅当数组被全部填满时,才能抛出栈溢出异常。也就是说,数组有空间时,可以支持任意栈的push()操作
思路:使用静态链表的结构方法,数组扩展成这样的结构,当前值,上一个元素的索引,同时增加三个变量保存三个栈的栈顶,这样类似链表的结构在退栈时就能找到新的栈顶,解决了POP;
那么PUSH呢?同样利用一个静态链表,表示当前数组空的空间,初始值为全部数组,每按顺序进栈一个就将表头指向下一个空间(相当于删除表头);当某栈靠前的位置出栈(比如124栈A,356栈B,当前空链表头为7,栈A退栈,索引指向4),则将索引指向新空出来的位置(相当于插入到表头).
两个队列构造一个栈:利用其中一个队列始终保存一个元素(即栈顶)
1.PUSH:如果队列A为空,进入队列A;如果A不空,A出队进B队列,再进A队列,保持A元素只有一个;
2.POP:假设A队列只有一个元素,A出队,返回该数据即为栈顶,然后B出队到只剩下一个元素,出队元素再进入A队列,这时B中保存的是栈顶;
利用栈的基本运算将指定栈中的内容进行逆转
利用栈的基本运算返回指定栈中的栈底元素
设计栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
应用
数制转换
括号匹配的检验
行编辑程序
迷宫求解
表达式求值
递归的原理