数据结构与算法(C++版):表、栈和队列

前言

本系列博客为学习数据结构与算法过程中的原创笔记,其中代码实现基于C++语言。

STL中的向量和表

在C++语言的库中包含有公共数据结构的实现,这就是众所周知的标准模版库(Standard Template Library, STL)。表就是STL实现的数据结构之一。
表有两个流行的实现。
vector给出了表的可增长的数组实现。使用vector的优点是长度可自由控制,且在常量的时间里是可索引的。缺点是插入和删除操作的代价是昂贵的,除非操作发生在vector的末尾。
list提供了表的双向链表实现。
使用list的优点是, 如果变化发生的位置已知的话, 插入新项和删除已有项的代价是很小的。
缺点是list不容易索引。
vector和list两者在查找时效率都很低。此类型的数据结构,都有公共的方法,下述的前三个方法事实上对所有的STL容器都适用。

  • int size() const:返回容器内的元素个数。
  • void clear():删除容器内所有元素。
  • bool empty():如果容器为空返回true,否则返回false。

vector和list都支持在表的末尾进行访问和操作。

  • void push_back( const Object & x ):在表的末尾添加x。
  • void pop_back():删除表的末尾对象。
  • const Object & back() const:返回表的末尾的对象。
  • const Object & front() const:返回表的末尾的对象。

双向链表允许在表的前端进行高效的改变,下面方法只对list有效。

  • void push_front( const Object & x): 在list的前端添加x。
  • void pop_front( ): 在list的前端删除对象。

vector也有list所不具有的特有的方法。 有两个方法可以进行高效的索引。 另外两个方法允许程序员观察和改变vector的内部容量。

  • Object & operator[] (int idx): 返 回vector中idx索引位置的对象, 不包含边界检
    测( 也提供返回常量引用的访问函数)。
  • Object & at ( int idx ): 返 回vector中idx索引位置的对象, 包含边界检测( 也提供返回常量引用的访问函数)。
  • int capacity( ) const: 返回vector的内部容量。
  • void reserve( int new Capacity ): 设 定vector的新容量。 如果己有良好的估计的话, 这可以避免对vector进行扩展。

迭代器

迭代器是一种检查容器内元素并遍历元素的数据类型。可以替代下标访问vector对象的元素。
迭代器通过iterator给出。例如,对于list<string>,定义为list<string>::iterator,对与vector<int>,定义为vector<int>::iterator。
以下列举迭代器一些相关的方法和操作。

  • iterator begin():返回指向容器的第一项的迭代器。
  • iterator end():返回指向容器的终止标志的迭代器(容器最后一项后面的位置)。
  • iter++和++iter:推进迭代器至下一个位置。
  • *iter:返回存储在迭代器iter指定位置的对象的引用。

下述代码列举了一个简单的对vector进行迭代器操作的使用。

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> data1 = {1, 2, 4, 6, 8}, data2; //定义data1, data2并初始化data1
    vector<int>::iterator iter; //定义迭代器
    cout << "data1 =";
    for(iter = data1.begin(); iter != data1.end(); iter++) //迭代器的循环条件
    {
        cout << " " << *iter; //输出data1
        data2.push_back(*iter); //向data2写数据
        data2.push_back((*iter) * 2);
    }
    cout << endl << "data2 =";
    for(iter = data2.begin(); iter != data2.end(); iter++)
    {
        cout << " " << *iter;
    }
    cout << endl;
    return 0;
}

(stack)是限制插入和删除操作只能在一个位置上的表,这个位置是表的末端,称作栈的(top),栈顶元素是唯一可见(可访问)的元素。栈的基本操作有push(进栈)和pop(出栈)两种。栈有时又被称作LIFO(后进先出)表。
栈的实现比较简单,此处不再详细介绍。
在C++的STL中,对栈进行了封装,加入头文件#include <stack>即可调用,其共有五个常用操作函数top()、push()、pop()、size()和empty(),STL中栈的操作如下:

  • stack<Elemtype > StackElem 创建一个空的stack对象
  • StackElem.top() 返回栈顶数据。
  • StackElem.push(elem) elem入栈
  • StackElem.pop() 弹出栈顶元素(出栈)
  • StackElem.size() 返回栈中数据的个数
  • StackElem.empty() 判断栈是否为空

下面代码是一个简单的栈的使用范例,包含上述所有函数。

#include <iostream>
#include <list>
#include <stack>

using namespace std;

int main()
{
    /* * stack不是一种数据结构,是一种容器适配器(container adapter), * 因此它需要一个基础的容器来存储,这个容器可以是vector, deque,list * 等标准容器,未指定时默认是deque。 */
    stack<string> stackTest; //定义栈stackTest存储数据类型为string
    string words;
    for(int i = 0; i < 5; i++)
    {
        cin >> words;
        stackTest.push(words); //words入栈
    }
    cout << stackTest.size() << endl; //输出栈元素个数
    while(!stackTest.empty()) //栈是否为空
    {
        cout << stackTest.top() << " "; //输出栈顶元素
        stackTest.pop(); //出栈
    }
    cout << endl;
    return 0;
}

队列

队列(queue)也是以表存储数据,但只允许从表的两端访问元素,而且限定从表的一端读入数据,从另一端读出数据。队列跟栈类似,没有迭代器,不能遍历,跟栈不同的地方是它属于FIFO(先进先出)表。
queue的实现也是基于list,本文主要讲用法,因此不再介绍具体实现,可参考《STL源码剖析》一书。
在C++的STL中,同时也对queue进行了封装,加入头文件#include <queue>即可调用,其共有五个常用操作函数front()、back()、push()、pop()、size()和empty(),与栈的常用函数类似。STL中queue的操作如下:

  • queue<Elemtype > queueElem 创建一个空的queue对象
  • queueElem.front() 返回队列头部数据
  • queueElem.back() 返回队列尾部数据
  • queueElem.push(elem) 向队列尾部添加数据elem
  • queueElem.pop() 队列头部数据出队
  • queueElem.size() 返回队列中数据的个数
  • queueElem.empty() 判断队列是否为空

下面代码是一个简单的队列的使用范例,包含上述所有函数。

#include <iostream>
#include <queue>
#include <list>

using namespace std;

int main()
{
    queue<string, list<string> > queueTest; //跟栈一样,此处用list存储
    string words;
    for(int i = 0; i < 5; i++)
    {
        cin >> words;
        queueTest.push(words); //队首入队
    }
    cout << queueTest.size() << " " << queueTest.back() <<endl; //输出队列长度和队尾元素
    while(!queueTest.empty())
    {
        cout << queueTest.front() << " " << endl; //输出队首元素
        queueTest.pop(); //出队
    }

    return 0;
}

如你所见,本文只是简单的介绍了表,vector,栈和队列,而且并没有详细介绍各自的实现,只是借助STL介绍了他们的一些基础用法,希望对你有所帮助。

    原文作者:停车场模拟问题
    原文地址: https://blog.csdn.net/u013271326/article/details/72876557
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞