• Stack容器


    1、Stack

    (1)定义

    栈是一种容器适配器,特别为后入先出而设计的一种(LIFO ),那种数据被插入,然后再容器末端取出。

    默认情况下,如果没有容器类被指定成为一个提别的stack 类,标准的容器类模板就是deque 队列。

    堆栈是一个线性表,插入和删除只在表的一端进行。这一端称为栈顶(Stack Top),另一端则为栈底(Stack Bottom)。堆栈的元素插入称为入栈,元素的删除称为出栈。由于元素的入栈和出栈总在栈顶进行,因此,堆栈是一个后进先出(Last In First Out)表(queue是FIFO),即 LIFO 表。

    (2)底层实现

    实现C++  STL,栈有两个参数:

    template < class T, class Container = deque<T> > class stack;

    参数示意:

    T: 元素类型
    Container: 被用于存储和访问元素的的类型

    C++ STL 的堆栈泛化是直接通过现有的序列容器来实现的,默认使用双端队列deque的数据结构。

    当然,可以采用其他线性结构(vector 或 list等),只要提供堆栈的入栈、出栈、栈顶元素访问和判断是否为空的操作即可。

    由于堆栈的底层使用的是其他容器,因此,堆栈可看做是一种适配器,将一种容器转换为另一种容器(堆栈容器)。

    为了严格遵循堆栈的数据后进先出原则,stack 不提供元素的任何迭代器操作,因此,stack 容器也就不会向外部提供可用的前向或反向迭代器类型。

    拓展:

    Q:为什么stack和queue没有迭代器?让这些容器具备迭代器岂不是更方便?

    A:一个容器的方法与其本身特性密切联系,stack和queue分别是FILO和FIFO的线性表,不允许其他的进出方式,为了严格遵守这种原则,故不提供迭代器操作。deque是双向队列,提供迭代器。

    (3)使用

    stack堆栈容器的C++标准头文件为 stack ,必须用宏语句 "#include <stack>" 包含进来,才可对 stack 堆栈的程序进行编译。

    2、成员函数

    (1)创建 stack 对象

    使用堆栈前,先要利用构造函数进行初始化,创建一个堆栈对象,以进行元素的入栈、出栈等操作。
    1. stack()
    默认构造函数,创建一个空的 stack 对象。
    例如,下面一行代码使用默认的 deque 为底层容器,创建一个空的堆栈对象 s 。
    stack<int>  s;
    
    
    
    2. stack(const stack&) 
    复制构造函数,用一个stack堆栈创建一个新的堆栈。 例如,下面的代码利用s1,创建一个以双向链表为底层容器的空堆栈对象 s2 。
    // stack<int, list<int> >   s1;
    stack<int, list<int> >   s2(s1);
    

      

    (2)元素入栈

    stack堆栈容器的元素入栈函数为push函数。

    由于 C++ STL 的堆栈函数是不预设大小的,因此,入栈函数就不考虑堆栈空间是否为满,均将元素压入堆栈,从而函数没有标明入栈成功与否的返回值。

    如下是他的使用原型:

    void  push(const value_type& x)
    void push ( const T& x ); 

    示例:

    // stack::push/pop
    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main ()
    {
      stack<int> mystack;
    
      for (int i=0; i<5; ++i) mystack.push(i);
    
      cout << "Popping out elements...";
      while (!mystack.empty())
      {
         cout << " " << mystack.top();
         mystack.pop();
      }
      cout << endl;
    
      return 0;
    }
    //output:Popping out elements... 4 3 2 1 0

    (3)元素出栈

    stack容器的元素出栈函数为 pop 函数,由于函数并没有判断堆栈是否为空,才进行元素的弹出,因此,需要自行判断堆栈是否为空,才可执行 pop 函数。

    void pop()

    示例:

    下面的示例代码,将堆栈的所有元素全部出栈
    // stack<int>  s;
    while(!s.empty())
    { 
       s.pop();// 出栈
    }
    
    // stack::push/pop
    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main ()
    {
      stack<int> mystack;
    
      for (int i=0; i<5; ++i) mystack.push(i);
    
      cout << "Popping out elements...";
      while (!mystack.empty())
      {
         cout << " " << mystack.top();
         mystack.pop();
      }
      cout << endl;
    
      return 0;
    }
    //output:Popping out elements... 4 3 2 1 0
    

      

    (4)取栈顶元素

    value_type&  top()
    
    value_type& top ( );
    const value_type& top ( ) const;

    示例:

    // test_stack.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <stack>
    #include <vector>
    #include <deque>
    #include <iostream>
    
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	stack<int> mystack;
    	mystack.push(10);
    	mystack.push(20);
    	mystack.top()-=5;
    	cout << "mystack.top() is now " << mystack.top() << endl;
    
    	return 0;
    }
    //output:
    
    mystack.top() is now 15

    (5)堆栈非空判断

    随着堆栈元素不断出栈,堆栈可能会出现空的情况,因此,一般需要调用 empty 函数判断是否非空,才作元素出栈和取栈顶元素的操作

    bool  empty()
    //判断堆栈是否为空,返回 true 表示堆栈已空,false 表示堆栈非空。

    示例:

    // stack::empty
    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main ()
    {
      stack<int> mystack;
      int sum (0);
    
      for (int i=1;i<=10;i++) mystack.push(i);
    
      while (!mystack.empty())
      {
         sum += mystack.top();
         mystack.pop();
      }
    
      cout << "total: " << sum << endl;
      
      return 0;
    }
    //output:55

    (6)访问栈中的元素个数

    堆栈的元素个数可用 size 函数获得。每次元素入栈前,先检查当前堆栈的大小,超过某个界限值,则不允许元素入栈,以此可实现一个具有一定容量限制的堆栈。

    size_type size ( ) const;
    //计算栈对象元素个数

    示例:

    // stack::size
    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main ()
    {
      stack<int> myints;
      cout << "0. size: " << (int) myints.size() << endl;
    
      for (int i=0; i<5; i++) myints.push(i);
      cout << "1. size: " << (int) myints.size() << endl;
    
      myints.pop();
      cout << "2. size: " << (int) myints.size() << endl;
    
      return 0;
    }
    //output:
    
    0. size: 0
    1. size: 5
    2. size: 4
    

      

  • 相关阅读:
    python 学习笔记(四)(流程控制)
    python 写斐波那契数列
    python 部分术语对照表
    python 学习笔记(三)(对前两节的补充)
    python # -*- coding: utf-8 -*-
    写出更好的 JavaScript 条件语句
    PHP消息队列实现及应用
    VUE3.0 路由去掉#号
    php设计模式
    workerman 可能需要用到的函数
  • 原文地址:https://www.cnblogs.com/yedushusheng/p/5519887.html
Copyright © 2020-2023  润新知