C++语言实现链式栈
在之前写的C语言实现链式栈篇博文中,我已经给大家大概介绍了关于链式栈的意义以及相关操作,我会在下面给大家分享百度百科对链式栈的定义,以及给大家介绍利用C++实现链式栈的基本操作。
百度百科链式栈
链式栈是一种数据存储结构,可以通过单链表的方式来实现,使用链式栈的优点在于它能够克服用数组实现的顺序栈空间利用率不高的特点,但是需要为每个栈元素分配额外的指针空间用来存放指针域。
栈是只能在某一端插入和删除的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底(push),最后的数据在栈顶(top),需要读数据的时候从栈顶开始弹出数据(top)最后一个数据被第一个读出来。链式栈中的元素以Node的形式存储,节点Node中存有此节点存于栈中的元素以及指向下个节点的指针。链式栈的数据成员只用保存指向栈顶节点的指针 *top_node。
顺序栈的实现在于使用了数组这个基本数据结构,数组中的元素在内存中的存储位置是连续的,且编译器要求我们在编译期就要确定数组的大小,这样对内存的使用效率并不高,一来无法避免因数组空间用光而引起的溢出问题,二在系统将内存分配给数组后,则这些内存对于其他任务就不可用;而对于链栈而言,使用了链表来实现栈,链表中的元素存储在不连续的地址,由于是动态申请内存,所以我们可以以非常小的内存空间开始,另外当某个项不使用时也可将内存返还给系统。
C++实现链式栈
利用C++语言实现了数据结构的链式栈,主要完成了以下操作:
链式栈的 | 基本操作 |
---|---|
元素进栈 | 元素出栈 |
返回栈顶元素 | 判断栈是否为空 |
打印栈的元素 |
链式栈的结点
链式栈的结点其实跟链式结构的顺序结构差不多类似,包含两部分,一是储存数据的数据域,二是储存下一结点地址的指针域,因此以结构体封装的结点如下:
template <class T>
struct chainStackNode
{
T data;//链式栈储存结点的数据
chainStackNode<T> *next;//链式栈指向下一结点的指针
};
链式栈的基本操作
在写这次链式栈的时候,我在所有的函数实现前都加上了inline,在这里给大家解释一下。inline是C++关键字,在函数声明或定义中,函数返回类型前加上关键字inline,即可以把函数指定为内联函数。这样可以解决一些频繁调用的函数大量消耗栈空间(栈内存)的问题。关键字inline必须与函数定义放在一起才能使函数成为内联函数,仅仅将inline放在函数声明前面不起任何作用。inline是一种“用于实现”的关键字,而不是一种“用于声明”的关键字。
构造函数
构造函数,就是实现成员的初始化操作,当然在这里实现链式栈的初始化就只需要创建一个头指针,并初始化头指针的各个成员。
template <class T>
inline chainStack<T>::chainStack()
{
top = new chainStackNode<T>;//创建一个新的结点
top->next = NULL;//将top的next指针指向空
}
元素进栈
链式栈的进栈操作,顾名思义就是一个新的元素进入栈,当然首先要创建一个新的结点,然后就是将这个新的结点插入到栈顶,只需要调整来两个指针操作。
template <class T>
inline bool chainStack<T>::Push(T newData)
{
chainStackNode<T> *newNode = new chainStackNode<T>;
if(!newNode){
cout<<"分配内存失败!"<<endl;
return false;
}
newNode->data = newData;//修改指针,添加元素
newNode->next = top->next;
top->next = newNode;
return true;
}
元素出栈
元素出栈,就跟线性表的删除元素类似,不过只能删除顶部结点,这个栈的特性是不可以违背的,调整指针删除结点之后不要忘了释放删除的结点的内存。
template <class T>
inline bool chainStack<T>::Pop(T &x)
{
chainStackNode<T> *temporaryNode;//创建一个临时指针指向删除结点
if(isEmpty() == true){
cout<<"该栈为空!"<<endl;
return false;
}
else
{
temporaryNode = top->next;
x = temporaryNode->data;//以引用返回
top->next = temporaryNode->next;
delete temporaryNode;//释放空间
return true;
}
}
返回栈顶元素
返回栈顶的元素,判断栈是否为空,如果为空自然没有元素可以返回,否则就返回top指向的下一个结点的数据即可。
template <class T>
inline bool chainStack<T>::getTop(T &x)
{
if(isEmpty() == true){
return false;
}
else{
x = top->next->data;
return true;
}
}
判断栈是否为空
有了top指针,就只需要判断top指针的下一结点是否为空即可。
template <class T>
inline bool chainStack<T>::isEmpty()
{
if(top->next == NULL){//top指针的下一结点是否为空,以此来判断是否为空
return true;
}
else{
return false;
}
}
打印栈的元素
打印栈的元素,就是一个遍历的过程,定义一个指针,输出结点数据,调整指针位置。
template <class T>
inline void chainStack<T>::printChainStackData()
{
chainStackNode<T> *pMove;
pMove = top->next;
while(pMove->next != NULL){
cout<<"["<<pMove->data<<"]->";
pMove = pMove->next;
}
cout<<"["<<pMove->data<<"]"<<endl;
}
到这里,利用C++语言实现链式栈的介绍就已经结束了,如果有哪里写的不好的地方,还希望大家给我提出了,我加以修正,完整的代码包括测试代码我已经push到了githubC++实现链式栈,另外如果大家还想了解其他的内容,欢迎来我的博客,我们一起讨论,共同进步!