一、栈的基本概率
1、栈的定义:栈是一种只能在一端进行插入或删除操作的线性表。表中允许进行插入、删除操作的一端称为栈顶。栈顶的位置是动态的,栈顶的当前位置由一个称为栈顶指针的位置指示器来指示,栈的另一端称为栈底,当栈中没有数据元素的时候称为空栈。栈的插入称为入栈或者进栈。栈的删除称为出栈或者退栈。
2、栈的特点:主要特点为“先进后出”,及后进栈的数据先出战。栈也称为后进先出表
3、栈的基本运算
InitStack(&st); //初始化栈,构造有个空栈st StackEmpty(st); //判断栈是否为空,如果st栈为空则返回为真,否则为假 Push(&st,x); //进栈,将元素X插入到栈st中作为栈顶元素 Pop(&st,&x); //出栈,从栈st中退出栈顶元素,并将其赋值给x GetTop(st,&x); //取栈顶元素。返回当前栈顶元素,并将其赋值给x
4、栈的存储结构:顺序结构和链表结构
二、顺序栈的操作
1、顺序栈的定义:采用顺序存储结构存储栈,即分配一块连续的存储区域存放栈中元素,并用一个元素指向栈顶
定义栈类型SqStack
typedef struct { ElemType data[MaxSize]; int top; }SqStack; //栈空:st.top==-1; //栈满:st.top==MaxSize-1; //元素x进栈操作:st.top++; st.data[st.top]=x; //出栈x操作:x=st.data[st.top]; st.top--;
2、顺序栈的基本运算
(1)、初始化栈:将栈顶指针置为-1
void InitStack(SqStack &st) //初始化栈 { st.top=-1; }
(2)、判断栈是否为空算法:栈st为空时返回1,否则返回0
int StackEmpty(SqStack st) { return(st.top==-1) }
(3)、进栈算法:在栈不满的情况下,先将栈顶指针加一,然后在该位置插入元素x
int Push(SqStack &st,ElemType x) { if (st.top==MaxSize-1) { return 0; } st.top++; st.data[st.top]=x; return 1; }
(4)、出栈算法:在栈不为空的情况下,先将栈顶元素赋值给x,然后在将栈顶指针减一
int Pop(SqStack &st,ElemType &x) { if (st.top==-1) { return 0; } x=st.data[st.top]; st.top--; return 1; }
(5)、取栈顶元素算法:在栈不为空的情况下,返回当前栈顶元素,并将其赋值给x
int GetTop(SqStack &st,ElemType &x) { if (st.top==-1) { return 0; } x=st.data[st.top]; return 1; }
三、共享栈
顺序栈采用数组存放栈中的元素,如果需要用到两个相同类型的栈,这时若为它们各自开辟一个数组空间,但容易出现第一个栈满了,在进制就溢出了,而另一个还有很多的存储空间空闲,这时可以将两个栈合起来,用一个数组实现这两个栈,称为:共享栈
一个大小为MaxSize的数组,有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0,另一个栈的栈底为数组的末端,即下标为MaxSize-1,增加元素时,两端点向中间延伸
共享栈的要素
栈空:栈1空:top1==-1,栈2空 top2=MaxSize
栈满:top1==top2-1
元素x进栈操作:进栈1操作:top1++;data[top1]=x; 进栈2操作:top2--;data[top2]=x;
出栈x操作:出栈1操作:x=data[top1];top--; 出栈2操作:x=data[top2];top++;
四、链栈的操作
1.链栈的定义:采用链式存储结构存储栈。链栈的优点在于不存在栈满上溢的情况,所有操作都在单链表的表头操作
链表中数据节点的类型LiStack定义
typedef struct linknode { ElemType data; struct linknode *nextl }LiStack; //栈空:lst->next==NULL; //栈满:通常不存在栈满的情况 //元素*p进栈操作:p->next=lst->next;lst->next=p; //出栈元素x操作:p=lst->next;x=p->data;lst->next=p->next;free(p);
2、链表的基本运算
(1)、初始化栈:建立一个空栈st,实际上是创建链栈的头节点,并将其next赋值为NULL
void InitStack(LiStack &lst) //初始化栈 { lst=(LiStack *)malloc(sizeof(LiStack)); lst->next=NULL; }
(2)、判断栈是否为空算法:栈st为空时返回1,否则返回0
int StackEmpty(LiStack lst) { return(lst->next==NULL); }
(3)、进栈算法:将新节点插入到头节点之后
void Push(LiStack &lst,ElemType x) { LiStack *p; p=(LiStack *)malloc(sizeof(LiStack)); p->data=x; p->next=lst->next; lst->next=p; }
(4)、出栈算法:在栈不为空的情况下,将头节点的后继数据节点的数据域赋值给x,然后再将其删除
int Pop(LiStack &lst,ElemType &x) { LiStack *p; if (lst->next==NULL) { return 0; } p=lst->next; x=p->data; lst->next=p->next; free(p); return 1; }
(5)、取栈顶元素算法:在栈不为空的情况下,将头节点的后继数据节点的数据域赋值给x
int GetTop(LiStack &st,ElemType &x) { LiStack *p; if (lst->next==NULL) { return 0; } p=lst->next; x=p->data; lst->next=p->next; return 1; }