对于栈的定义,前人之述备矣。

我实现的是一个stack<value>容器类,支持push,pop,top,size,empty,clear和copy construction操作。

主要的实现思路是,先写出几个支持基本操作的类_stack_impl,然后再写一个包装类stack,包装基本操作,再实现size,copy struction,top,clear和抛出异常的功能。这样做(pImpl)的好处不言而喻。

我实现的copy structurion其实是用的一个包装了的友元函数_stack_copy(dst, src),因为这样可以直接访问底部成员并进行复制,比使用用户接口,先一个一个pop,再一个一个push,快多了。

代码使用C++11标准。如果有不对的地方,欢迎指出。

在Win7 mingw32 gcc4.7下编译并测试通过。测试内容非常简单,所以可能会有一些没测试出来的问题。

以下是实现

  1. #pragma once
  2. #include <cstddef>
  3. #include <stdexcept>
  4.  
  5. namespace jt {
  6.  
  7. template <class value>
  8. class stack {
  9. template <class v>
  10. friend void _stack_copy(stack<v>& dst, const stack<v>& src);
  11.  
  12. private:
  13. struct _stack_impl;
  14. _stack_impl *_impl = nullptr;
  15. size_t _siz;
  16.  
  17. void _init_empty() {
  18. _siz = ;
  19. if (_impl) delete _impl;
  20. _impl = new _stack_impl;
  21. }
  22.  
  23. void _destory() { _siz = ; delete _impl; }
  24.  
  25. public:
  26. stack() { _init_empty(); }
  27. stack(const stack<value> &o) { _stack_copy(*this, o); }
  28. ~stack() { _destory(); }
  29.  
  30. void clear() { _init_empty(); }
  31. void push(const value &val) { _impl->push(val); ++_siz; }
  32. size_t size() const { return _siz; }
  33.  
  34. value pop() {
  35. if (_siz == )
  36. throw std::out_of_range("jt::stack::pop() - Empty Stack");
  37. --_siz; return _impl->pop();
  38. }
  39.  
  40. bool empty() const { return _siz == ; }
  41.  
  42. value top() const {
  43. if (_siz == )
  44. throw std::out_of_range("jt::stack::top() - Empty Stack");
  45. return _impl->n->val;
  46. }
  47. };
  48.  
  49. template <class value>
  50. static void _stack_copy(stack<value> &dst, const stack<value> &src) {
  51. dst._init_empty();
  52. auto **dn = &dst._impl->n; // dest node
  53.  
  54. for (auto *s = src._impl->n; s; s = s->next) {
  55. *dn = new typename stack<value>::_stack_impl::node;
  56. (*dn)->val = s->val;
  57. dn = &(*dn)->next;
  58. }
  59.  
  60. dst._siz = src._siz;
  61. }
  62.  
  63. template <class value>
  64. struct stack<value>::_stack_impl {
  65. struct node {
  66. value val;
  67. node *next = nullptr;
  68. } *n = nullptr; // head/top
  69.  
  70. ~_stack_impl() {
  71. while (n) {
  72. auto *tmp = n->next;
  73. delete n;
  74. n = tmp;
  75. }
  76. }
  77.  
  78. void push(const value &val) {
  79. node *t = new node;
  80. t->val = val;
  81. t->next = n;
  82.  
  83. n = t;
  84. }
  85.  
  86. value pop() {
  87. value v = n->val;
  88.  
  89. node *tmp = n->next;
  90. delete n;
  91. n = tmp;
  92.  
  93. return v;
  94. }
  95. };
  96.  
  97. }

[C++][数据结构]栈(stack)的实现的更多相关文章

  1. C# 数据结构 栈 Stack

    栈和队列是非常重要的两种数据结构,栈和队列也是线性结构,线性表.栈和队列这三种数据结构的数据元素和元素的逻辑关系也相同 差别在于:线性表的操作不受限制,栈和队列操作受限制(遵循一定的原则),因此栈和队 ...

  2. java数据结构 栈stack

    栈(Stack) 栈(Stack)实现了一个后进先出(LIFO)的数据结构. 你可以把栈理解为对象的垂直分布的栈,当你添加一个新元素时,就将新元素放在其他元素的顶部. 当你从栈中取元素的时候,就从栈顶 ...

  3. 数据结构—栈(Stack)

    栈的定义--Stack 栈是只允许在末端进行插入和删除的线性表.栈具有后进先出的特性(LIFO ,Last In Fast Out). 学过数据结构的人都知道:栈可以用两种方式来实现,一种方法是用数组 ...

  4. 模板 - 数据结构 - 栈/Stack

    普通的栈大家都会写,STL的栈据说默认实现方式是deque,没关系反正deque跑得飞快. 这里收录的是一些奇怪的栈,当然双栈实现的队列收录在队列里面. 对顶栈 众所周知,栈可以维护一系列前缀和,包括 ...

  5. 数据结构----栈stack

    栈的概念与数据结构 栈(有时称为“后进先出栈”)是一个元素的有序集合,其中添加移除新元素总发生在同一端.这一端通常称为“顶部”.与顶部对应的端称为“底部”.栈的底部很重要,因为在栈中靠近底部的元素是存 ...

  6. python基本数据结构栈stack和队列queue

    1,栈,后进先出,多用于反转 Python里面实现栈,就是把list包装成一个类,再添加一些方法作为栈的基本操作. 栈的实现: class Stack(object): #初始化栈为空列表 def _ ...

  7. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  8. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  9. java数据结构——栈(Stack)

    学习数据结构与算法是枯燥的,但只有坚持不懈的积累,才会有硕果累累的明天. /** * 继续学习Java数据结构 ————栈 * 栈的实现其实还是使用数组,只不过我们不能直接访问数组下标,而是通过一个指 ...

随机推荐

  1. Yocto开发笔记之《Tip-stdlib库函数strtod返回nan错误》(QQ交流群:519230208)

    2015.04-imx_v2015.04_3.14.38_6ul_ga+g5d63276 (Jan 04 2016 - 18:07:08) FSL Community BSP : https://co ...

  2. Python Day3

    一.set集合 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 # 创建数值集合 list_1 = ...

  3. Web jquery表格组件 JQGrid 的使用 - 7.查询数据、编辑数据、删除数据

    系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...

  4. Android 签名证书

    Android APK的数字签名的作用和意义 http://blog.csdn.net/gaomatrix/article/details/6568191 http://jingyan.baidu.c ...

  5. Python之路Python3【第零篇】Python2 & Python3区别持续更新~

    print def print(self, *args, sep=' ', end='\n', file=None): # known special case of print "&quo ...

  6. passive 的事件监听器

    很久以前,addEventListener() 的参数约定是这样的: addEventListener(type, listener, useCapture) 后来,最后一个参数,也就是控制监听器是在 ...

  7. FireBug提示:本页面不包含 JavaScript,明明是包含js的。

    本页面不包含 JavaScript 如果 <script> 标签有 "type" 属性, 其值应为 "text/javascript" 或者 &qu ...

  8. Github.com上有哪些比较有趣的PHP项目?

    链接就不贴了,可以在github上进行搜索.这里就不列举 symfony.laravel 这些大家都知道的项目了.只列举比较有意思的. swoole, C扩展实现的PHP异步并行网络通信框架,可以重新 ...

  9. PHP操作SQL Server 2008/2012

    PHP操作SQL Server驱动,微软官方提供2个版本,Version 2.0 和 Version 3.0 Version 2.0 版本支持的操作系统有: Windows Server 2003 S ...

  10. MySQL 关联表批量修改(数据同步)

    update table1 t1 ,table2 t2 set t1.field1 = t2.field2 where t1.id = t2.id