目录
2.1 操作概述:初始化;销毁栈;判断栈是否为空;求栈的长度;取栈顶元 素;栈置空操作;入栈;出栈。
一.栈的相关概念:
1.1 定义:限定只能在表的一端进行插入和删除运算的线性表(只能在栈顶操作)。
1.2 逻辑结构:与线性表相同,仍为一对一的关系。
1.3 存储结构:用顺序栈和链栈存储,顺序栈更常见。
1.4 运算法则:只能在栈顶进行插入和删除,并且遵循先入后出的原则(Fisrt In Last Out : FILO) 。
1.5 实现方式:编写入栈和出栈函数,顺 序栈和链栈不同。
二.栈的相关操作
2.1 操作概述:初始化;销毁栈;判断栈是否为空;求栈的长度;取栈顶元 素;栈置空操作;入栈;出栈。
栈的结构所示:
2.2 顺序栈上的一些操作(栈的顺序存储)
2.2.1 空栈的标志:base == top;
栈满的标志: top - base == stacksize。(存在上溢出和下溢出两种情况)
为了方便操作top总指向栈顶元素之上的下标地址。
2.2.2 栈的初始化:
代码逻辑:
Status InitStack(Sqstcak &S)
S.base = new SElemType[MAXSIZE];//c++语法
//S.base = (SELemType*)malloc(MAXSIZE*sizeof(SElemType)); //c语法
if(!S.base) //如果栈底指针为0,则分配失败
exit ERROR;
S.top == S.base //初始化的时候,栈顶指针等于栈底指针
S.stacksize = MAXSIZE; //栈的大小赋予stacksize。
return OK;
图示如下:
2.2.3 求顺序栈的长度:
代码逻辑:
int StackLength(SqStack S)
{
return S.top - S.base;
return OK;
}
图示如下:
2.2.4 清空顺序栈
代码逻辑:
Status ClearStack(SqStack S)
{
if(S.base != 0)
S.top = S.base;
return OK;
}
(top指针向下移动一次,就删除一个元素,等到和base到一个位置了,也就全部清空啦~)
图示如下:
2.2.5 销毁顺序栈
代码逻辑:
Status DestoryStack( SqStack &S)
{
if(S.base) //如果栈存在
{
delete S.base;
S.stacksize = 0;
S.base = S.top = NULL;
}
return OK;
}
销毁是比较彻底的一种操作,分别把(1)栈底指针删除,然后让(2)栈底和栈顶指针指向空,(3)空间大小置为0即可。
2.2.6 顺序栈的入栈
(1)判断栈满了没有
(2)元素e放进去
(3)栈顶指针加一
代码逻辑:
Status Push(SqStack &S , SElemType e)
{
if(S.top - S,base == S.stacksize) //先判断栈是否满了。
return ERROR;
*S.top++ = e;
//*S.top = e; 上面这一步相当于下面这两步。
//S.top++;
return OK;
图示如下:
2.2.7 顺序栈的出栈
(1)判断栈是否为空
(2)把当前栈顶的元素取出来
(3)然后栈顶指针减去一
代码逻辑:
Status Pop(SqStack &S , SElemType &e)
{
if(S.top == S.base)
return ERROR;
e = *--S.top;
//上面这一步其实等价于
//--S.top;
//e = *S.top
return OK;
图示如下:(如果一开始栈顶指针就指向了栈底指针,所以这时候是个空栈,也就无法进行出栈操作。)
2.3 栈的链式表示和实现
链栈的基本图示如下:
2.3.1 链栈的初始化
代码逻辑:(就是构造出来一个空的栈,因为是空的,头指针指向空)
void InitStack(LinkStack &S)
{
S = NULL;
return OK;
}
2.3.2 链栈的入栈操作(在栈顶操作)
(1)开辟一块新内存p
(2) 插入到栈顶
(3) 让栈顶指针指向新结点P
代码逻辑:
Status Pust(LinkStack &S , SElemType e)
{
p = new StackNode;
p -> data = e;//数据域里面给上一个值e
p -> nest = S;//把新结点插入到栈顶
S = p; //让栈顶指针指向新结点p , 这时候S指向的就是新的栈顶
return OK;
图示如下:
2.3.3 链栈的出栈操作(在栈顶操作)
代码思想:(先把栈顶指针的数据域存到一个变量e上,先把栈顶指针赋给一个新的指针变量p,然后移动栈顶指针,把p释放掉,也就相当于删除了原来的栈顶指针,即出栈)
Status Pop(LinkStack &S , SElemType &e)
{
if(S == NULL) //如果链栈不为空
return ERROR;
e = S -> data;
p = S;
S = S -> next;
delete p;
return OK;
}
图示如下:
三.习题练习(来几个题目练一练)
1.一个栈的输入序列为1 2 3 4 5,则下列序列中不可能是栈的输出序列的是 ( )。
A. 2 3 4 1 5
B. 5 4 1 3 2
C. 2 3 1 4 5
D. 1 5 4 3 2
2.一个栈的入栈序列为1,2,3,...,n ,其出栈序列是 p 1 ,p 2 ,p 3 ,...p n 。若p 2 = 3,则 p 3 可能取值的个数是()
A. n-1
B. n-2
C. n-3
D. 不能确定。
3. 设栈的输入序列为 123…..n ,输出序列为 a1,a2,a3,……,an ,若存在 1<=k<=n ,使得 ak=n ,则当 k<=i<=n 时, ai 为 ()
A. n-i+1
B. n-(i-k)
C. i
D. 不确定
4. 两个顺序栈共享数组S【0…n-1】,其中第一个栈的栈顶指针top1的初始值为-1,第二个栈的栈顶指针top2的初始值为n,则判断该共享栈满的条件是( )
A. top2 + 2 = top1
B. top1 + 1 = top2
C. top1 + 2 = top2
D. top2 + 1 = top1
(以上题目来自 牛客网!!)