栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
1.InitStack(S)初始化:初始化一个新的栈。
2.Empty(S)栈的非空判断:若栈S不空,则返回TRUE;否则,返回FALSE。
3.Push(S,x)入栈:在栈S的顶部插入元素x,若栈满,则返回FALSE;否则,返回TRUE。
4.Pop(S)出栈: 若栈S不空,则返回栈顶元素,并从栈顶中删除该元素;否则,返回空元素NULL。
5.GetTop(S)取栈顶元素:若栈S不空,则返回栈顶元素;否则返回空元素NULL。
6.SetEmpty(S)置栈空操作:置栈S为空栈。
栈是一种特殊的线性表,因此栈可采用顺序存储结构存储,也可以使用链式存储结构存储。
1.置空栈
首先建立栈的空间,然后初始化栈顶指针。
SeqStack * Linklist() { SeqStack * s; s = (SeqStack *)malloc(sizeof(SeqStack)); s -> top = -1; return s; }
2.判空栈
int Empty(SeqStack *s) { if (s -> top == -1) { return -1; } else return 0; }
3.入栈
int Push(SeqStack *s, ElemType x) { if (s -> top == MAXSIZE - 1) { return 0; //栈满不能入栈 } else { s -> top++; s -> elem[s -> top] = x; return 1; } }
4.出栈
int Pop(SeqStack *s, ElemType *x) { if (Empty(s)) { return 0;//栈空不能出栈 } else { * x = s -> elem[s -> top];//栈顶元素存入 *x,返回 s -> top--; return 1; } }
5.取栈顶元素
ElemType GetTop(SeqStack *s) { if (Empty(s)) { return 0;//栈空 } else return (s -> elem[s - top]); }
利用顺序存储方式实现的栈称为顺序栈。类似于顺序表的定义,栈中的数据元素用一个预设的足够长度的一维数组来实现:datatype data[MAXSIZE],栈底位置可以设置在数组的任何一个端点,而栈顶是随着插入和删除而变化的,用一个int top来作为栈顶的指针,指明当前栈顶的位置,同样将data和top封装在一个结构中,顺序栈的类型描述如下:
#define MAXSIZE typedef struct{ datatype data[MAXSIZE]; int top; }SeaStack;
定义一个指向顺序栈的指针:
SeqStack* s;
通常0下标端设为栈底,这样空栈时栈顶指针top = -1;入栈时,栈顶指针加1,即s ->top++;出栈时,栈顶指针减1,即s ->top–。
首先建立栈空间,然后初始化栈顶指针。
SeqStack* Init_SeqStack(){ SeqStack* s; s = malloc(sizeof(SeqStack)); s -> top = -1; return s; }
int Empty_SeqStack(SeqStack* s){ if (s -> top == -1){ return 1; } else return 0; }
首先我们现需要判断栈是否满了,如果满了则无法进行入栈,如果没满则就入栈。
nt Push_SeqStack (SeqStack* s , datatype x){ if (s->top = MAXSIZE - 1){ return 0; } else s->top++; s->data[s->top] = x; return 1; }
先进行判断,如果栈空就不能出栈,否则就进行出栈操作
int Pop_SeqStack (SeqStack* s , datatype x){ if (Empty_SeqStack(s)){ return ; } else{ *x = s->data[s->top]; s->top--; return 1; } }
取栈顶元素和出栈操作一样,先判断栈是不是空栈,如果不是才能返回栈顶元素。
datatype Top_SeqStack(SeqStack* s){ if (Empty_SeqStack(s)){ return 0; } else return (s->data[s->top]); }
通常我们在创建一个程序的时候,常要用的多个栈,若采用顺序栈,会因为所需的栈空间的大小很难估计,产生有的栈溢出,有的栈还很空闲,若让多个栈共用一个足够大的连续存储空间,则可利用栈的动态特性使它们的存储空间互补,这就是栈的共享邻接空间。
栈的共享中最常见的是两栈的共享。假设两个栈共享一维数组stack[MAXNUM],则可以利用栈的“栈底位置不变,栈顶位置动态变化”的特性,两个栈底分别为-1和MAXNUM,而它们的栈顶都往中间方向延伸。因此,只要整个数组stack[MAXNUM]未被占满,无论哪个栈的入栈都不会发生上移。两栈共享的数据结构定义为:
typedef struct{ Elemtype stack[MAXNUM]; int lefttop;/*左栈栈顶位置指示器*/ int righttop;/*右栈栈顶指示器*/ }dupsqstack;
1.初始化操作
int initDupStack(duosqstack* s){ /*创建两个共享邻接空间的空栈由指针s指出*/ if ((s == (dupsqstack*)malloc(sizeof(dupsqstack))) == NULL){ return FALSE; } s->lefttop = -1; s->righttop = MAXNUM; return TRUE; }
2.入栈操作
if (s->lefttop + 1 == s->righttop){ return FALSE; } if (status == 'L'){ s->stack[++s->lefttop] == x; } else if (status == 'R'){ s->stack[--s->lefttop] = x; } else{ return FALSE; } return TRUE; }
3.出栈操作
Elemtype popDupStack(dupsqstack* s , char status){ /*从左栈(status = 'L')或右栈(status = 'R')退出栈顶元素*/ if (status = 'L'){ if (s->lefttop < 0){ return NULL; } else return (s->stack[s->lefttop--]); } else if (status == 'R'){ if (s->righttop > MAXNUM - 1){ return NULL; } else return (s->stack[s->righttop++]); } else return NULL; }