这里我们通过C++实现一个链表栈结构,内核是链表,但是需要遵循栈的规则,并包含初始化空栈,判断栈是否为空,判断栈是否已满,插入元素,删除元素,获取栈顶元素,具体操作如下所示:

堆栈的基本操作

  • 初始化空栈:使用列表创建一个空栈,并令栈顶元素指针 self.top 指向 None,即 self.top = None
  • 判断栈是否为空:当 self.top == None 时,说明堆栈为空,返回 True,否则返回 False
  • 插入元素(进栈、入栈):创建值为 value 的链表节点,插入到链表头节点之前,并令栈顶指针 self.top 指向新的头节点。
  • 删除元素(出栈、退栈):先判断堆栈是否为空,为空直接抛出异常。如果堆栈不为空,则先使用变量 cur 存储当前栈顶指针 self.top 指向的头节点,然后令 self.top 沿着链表移动 1 位,然后再删除之前保存的 cur 节点。
  • 获取栈顶元素:先判断堆栈是否为空,为空直接抛出异常。不为空则返回 self.top 指向的栈顶节点的值,即 self.top.value

首先整体结构如下:

template <class T>
class Stack {public:Stack();Stack(const Stack &list_head);~Stack();public:bool Empty();void Push(T &val);void Push(T &&val);void Pop();T Top();public:int size() { return size_; }private:typedef struct Node {T val;Node* next;Node(T x) :val(x), next(NULL) {};}ListHead;int size_;Node* top;
};

如上图所示,这里定义了默认构造和拷贝构造,没定义有参构造。

然后是堆栈基础操作,判空,判满,入栈,出栈以及获取栈顶元素等操作。

最后还加了size(),用于判断链表中的数据是否存在。

数据成员则有两个,分别是当前的元素个数、栈指针。

接下来,我们看各自的实现。

1.初始化

template <class T>
Stack<T>::Stack():top(NULL),size_(0){}template <class T>
Stack<T>::Stack(const Stack& list_head) {Node* cur = list_head.top;  //得到指针this->size_ = list_head.size_;while (cur) {Node* temp = new Node(cur->val); // 拷贝数据temp->next = this->top;this->top = temp;cur = cur->next;}
}template <class T>
Stack<T>::~Stack() {if (this->top != NULL) {while (this->top != NULL) {Node* temp = top->next;delete top;top = temp;}}
}

上面三个分别为默认构造,拷贝构造和析构函数。

其中析构函数,对链表还剩余的节点都进行了析构。

拷贝构造函数,则是采用的深拷贝,重新在堆区开辟了空间。

2.判空

template <class T>
bool Stack<T>::Empty() {return NULL==top;
}

判空实现比较简单,top指针等于NULL就可以了。

3.压栈

template <class T>
void Stack<T>::Push(T &val) {Node* cur = new Node(val);cur->next = this->top;this->top = cur;this->size_++;
}template <class T>
void Stack<T>::Push(T&& val) {Node* cur = new Node(val);cur->next = this->top;this->top = cur;this->size_++;
}

这里压栈的值为自定义类型,虽然内部结构实现是指针,但是对外还是以正常数据类型进行压栈。

之所以还需要重载一个Push函数,是因为不能对右值取引用

4.出栈

template <class T>
void Stack<T>::Pop() {if (Empty()) {cout << "stack is empty" << endl;}else {size_--;Node* temp = top->next;  //移动一格delete top; //析构top = temp;}
}

除了将top指针向前进一步之外,还需要进行节点的析构。

5.获取首部元素

template <class T>
T Stack<T>::Top() {if (Empty()) {cout << "stack is empty" << endl;}else {return this->top->val;}
}

直接通过首部的指针进行访问即可。

最后是测试代码:

测试了int和string两种数据类型,均可以实现。

int main()
{Stack<string> s;cout << s.Empty() << endl;s.Push("nihao");s.Push("wohao");s.Push("tahao");s.Push("dajiahao");s.Push("buhao");s.Pop();cout << s.size() << endl;Stack<string> test(s);  //测试拷贝构造函数while (!test.Empty()) {cout << test.Top() << "\t";test.Pop();}  cout << endl;/***************int****************/Stack<int> s_int;cout << s.Empty() << endl;s_int.Push(4);s_int.Push(5);s_int.Push(6);s_int.Push(8);s_int.Push(9);s_int.Pop();while (!s_int.Empty()) {cout << s_int.Top() << "\t";s_int.Pop();}  cout << endl;return 0;
}

老规矩,有用二连,感谢大家。

C++数据结构之链表栈相关推荐

  1. 数据结构 线性链表栈

    #ifndef _MY_LINKSTACK_H_ #define _MY_LINKSTACK_H_typedef void LinkStack;//创建链表栈 LinkStack* LinkStack ...

  2. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  3. Java实现自定义队列和树结构_Java数据结构之链表、栈、队列、树的实现方法示例...

    本文实例讲述了java数据结构之链表.栈.队列.树的实现方法.分享给大家供大家参考,具体如下: 最近无意中翻到一本书,闲来无事写几行代码,实现几种常用的数据结构,以备后查. 一.线性表(链表) 1.节 ...

  4. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

  5. DSt:数据结构的简介、最强学习路线(逻辑结构【数组-链表-栈和队列/树-图-哈希】、物理结构、数据运算【十大排序/四大查找-图三大搜索-树三大遍历】、高级算法【贪心/分治/动态规划】之详细攻略

    DSt:数据结构的简介.最强学习路线(逻辑结构[数组-链表-栈和队列/树-图-哈希].物理结构[元素/关系].数据运算[十大排序/四大查找-图三大搜索-树三大遍历].高级算法[贪心/分治/动态规划]) ...

  6. 【数据结构】顺序栈与链表栈

    顺序栈 头文件 1 //@ author 成鹏致远 2 //@ net http://infodown.tap.cn 3 //@ qq 552158509 4 //@ blog lcw.cnblogs ...

  7. java链表的数据结构_Java数据结构 获取链表(LinkedList)的第一个和最后一个元素

    Java数据结构 获取链表(LinkedList)的第一个和最后一个元素 以下实例演示了如何使用 LinkedList 类的 linkedlistname.getFirst() 和 linkedlis ...

  8. 假设以带头结点的循环链表表示队列_JavaScript数据结构之链表--设计

    上一篇文章中介绍了几种常见链表的含义,今天介绍下如何写出正确的链表代码. 如何表示链表 我们一般设计的链表有两个类.Node 类用来表示节点,LinkedList 类提供了一些辅助方法,比如说结点的增 ...

  9. 数据结构之链表及其Java实现_数据结构之链表及其Java实现

    数据的存储一般分线性存储结构和链式存储结构两种.前者是一种顺序的存储方式,在内存中用一块连续的内存空间存储数据,即逻辑上相连的物理位置相邻,比较常见的就是数组:后者是一种链式存储方式,不保证顺序性,逻 ...

最新文章

  1. 2021年大数据常用语言Scala(二十二):函数式编程 映射 map
  2. unix mysql_Unix和Mysql中列出的数据库大小之间存在差异
  3. 使用win32 API 下载文件
  4. Git 企业中常用分支管理策略
  5. LAMP笔记之MySQL篇(2)
  6. HTTP管线化(HTTP pipelining)
  7. 微课|中学生可以这样学Python(5.5.3节):字符串格式化2
  8. 安装部署elasticsearch过程详解
  9. JavaScript中的加密解密
  10. BC26连接阿里云,MQTT协议,AT流程和STM32代码实现
  11. 计算机表格布局,使用表格布局网页
  12. [Netlist29-358] Reg ‘Counter[7]‘ of type ‘FDCPE’ cannot be timed accurately. Hardwarebehavior may be
  13. Coldfusion的基础知识
  14. 编解码学习笔记(三) Mpeg系列——Mpeg 1和Mpeg 2
  15. 从感性和理性的角度谈APS系统
  16. Ubuntu20.04 向日葵无法被远控的解决办法
  17. IPv6双栈技术方案
  18. win10 64位搭建汇编环境debug
  19. [多校联考-初级]徒步旅行
  20. R语言计算加权平均值:weighted.mean函数计算加权平均值、matrixStats包的weightedMean函数计算加权平均值、SDMTools包的wt.mean函数计算加权平均值

热门文章

  1. 苹果被5家公司组团起诉侵犯7项专利 涉及iPhone等三大类产品
  2. 【Unity3D读取数据】(二)Json文件操作(创建、读取、解析、修改)
  3. RabbitMQ入门指南:初学者也能读懂的教程
  4. POJ1017题解(语音讲解题意以及样例分析)
  5. 100种思维模型之递弱代偿原理思维模型-95
  6. mysql数据库常规备份还原 (常用增量备份)2018_lcf
  7. 摩托罗拉将第1个推出内置Linux软件的手机
  8. 勇士的库杜挡拆被高估了吗?
  9. 为什么32位的操作系统最多只能处理4GB的内存
  10. 运用Axure模仿美团网首页