3.1.2栈的概念与实现(2)

一、栈类的实现

前期讲述了栈的两种存储方式,但我们并不想去区分这两类的具体实现的应用差别,所以我们像线性表一样采用类的方式来解决这个问题。

    • 栈的抽象类

纯虚函数virtual表示我们不在抽象类中实现它,而是在它的子类中实现;const表示函数在实现过程中数据成员不会发生改变。

2.栈的抽象类的派生类——顺序栈类

顺序栈是seqStack,继承了stack,右小角的stack函数是seqStack的父类。

private为私有的说明

凡是顺序类存储的结构,都是用数组的形式来实现的。

栈顶的指针指向数组最后一个元素的下标位置。

数组的容量为maxsize,doublespace是将数组动态增加扩容的函数。

这些都是可以从父类的stack里面继承的。

①顺序栈类的五种实现形式(包括publicdeleteisEmptypushpop以及top

先创建了一个连续空间的数组,maxsize为10

top_p为-1而不是0;

delete[]elem是删除所有元素,缺少了“[]”则删除第一个元素。

注意在push中当我们doublespace之后,应该使用++top_p而不是top_p++;(注意++的语法)

而在出栈pop中,我们先返回top_p指向的值,然后在将其减去1,与push相反

②doubleSpace的类定义

注意:这个操作是把我们的数组扩大为原先的两倍长,但并非申请一个空间在原数组的后面,而是申请一个随机的且是原来空间两倍的一个新空间,将原数据复制在新的数组中,并将原数组删除。

如果是用链接方式存储,由于其存储方式的特性,都是我们需要多少空间当下就给我们多少空间,所以在push中并不需要doublespace这个函数。

3.第二种派生类——链接栈类

连接栈的空间不连续,所以需要指针去指向下一个结点的位置,每个元素结点都包含数据datanext或空指针两部分。

在这里我们采用结构体的方式进行定义结点的类型与结构,如下图:

此处为linkStack,上面的顺序栈类为seqStack;

有两种设置结点的方式,如图第七、八行是设置一个指定有数据和next指针指向的结点,而九、十行是设置一个空结点。

①链接栈相应操作的实现

此处的elem为头指针;

第六行注意顺序,先设置新结点的next指针与原先头指针相同,后再将头指针与tmp*一样指向新结点

其余与上方顺序类栈的实现相似,较为简单,略过。

②析构函数(将整个栈删除)

其主要的步骤就是将栈顶的元素一个一个释放掉,代码易读,略过。

4.STL中的栈

Vector(线性表顺序实现)可以理解为一个射线,改变和删除一定是在尾部的,上一节提到过在首部进行操作会非常麻烦;

List(双链表实现)则是两端进行操作的快捷性是相同的,但搜寻结点需要采用遍历的方式,不像数组那么便捷,可以直接用at()函数查找。

Deque则是采取上方两种方法的折中,它可以两端来操作,但是要实现栈,根据定义只能用一端进行操作,List同理,支持该操作但不能使用。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值