C++标准模板库与数据结构的学习

STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。

体验STL中的list

STL中提供的list类,是一个双向循环链表类。从每一个元素(节点),都可以访问前面一个元素和后面一个元素。在STL中,list提供了一系列的成员函数,实则完成的就是链表中的基本运算,以及其他在数据结构中不作为基本运算,但在工程中常用到的功能。

例如:

int data[6]={3,5,7,9,2,4}; 
list<int> lidata(data, data+6);  //list是个模板类,用<int>表明,其数据元素为int型
lidata.push_back(6); 
...

  list初始化时,申请的空间大小为6,存放下了data中的6个元素,当向lidata插入第7个元素“6”时,list申请新的节点单元,插入到list链表中,数据存放结构如下图所示:

C++标准模板库与数据结构的学习

list用在程序中
下面的程序,演示了使用list的更完整的过程。可以看到,只要在头部使用#include (该头文件提供class list的声明),list类中预置的功能即能够方便地使用,并且,数据元素的类型,依靠着模板机制可以自由使用。

#include <iostream>
#include <list>
#include <numeric>
#include <algorithm>

using namespace std;

//创建一个list容器的实例LISTINT
typedef list<int> LISTINT;

//创建一个list容器的实例LISTCHAR
typedef list<char> LISTCHAR;

int main()
{
    //--------------------------
    //用list容器处理整型数据
    //--------------------------
    //用LISTINT创建一个名为listOne的list对象
    LISTINT listOne;
    //声明i为迭代器
    LISTINT::iterator i;

    //从前面向listOne容器中添加数据
    listOne.push_front (2);
    listOne.push_front (1);

    //从后面向listOne容器中添加数据
    listOne.push_back (3);
    listOne.push_back (4);

    //从前向后显示listOne中的数据
    cout<<"listOne.begin()--- listOne.end():"<<endl;
    for (i = listOne.begin(); i != listOne.end(); ++i)
        cout << *i << " ";
    cout << endl;

    //从后向后显示listOne中的数据
    LISTINT::reverse_iterator ir;
    cout<<"listOne.rbegin()---listOne.rend():"<<endl;
    for (ir =listOne.rbegin(); ir!=listOne.rend(); ir++)
    {
        cout << *ir << " ";
    }
    cout << endl;

    //使用STL的accumulate(累加)算法
    int result = accumulate(listOne.begin(), listOne.end(),0);
    cout<<"Sum="<<result<<endl;
    cout<<"------------------"<<endl;

    //--------------------------
    //用list容器处理字符型数据
    //--------------------------

    //用LISTCHAR创建一个名为listOne的list对象
    LISTCHAR listTwo;
    //声明i为迭代器
    LISTCHAR::iterator j;

    //从前面向listTwo容器中添加数据
    listTwo.push_front ('A');
    listTwo.push_front ('B');

    //从后面向listTwo容器中添加数据
    listTwo.push_back ('x');
    listTwo.push_back ('y');

    //从前向后显示listTwo中的数据
    cout<<"listTwo.begin()---listTwo.end():"<<endl;
    for (j = listTwo.begin(); j != listTwo.end(); ++j)
        cout << char(*j) << " ";
    cout << endl;

    //使用STL的max_element算法求listTwo中的最大元素并显示
    j=max_element(listTwo.begin(),listTwo.end());
    cout << "The maximum element in listTwo is: "<<char(*j)<<endl;
    return 0;
}

list类中的成员函数
  list中提供了丰富的成员函数,用于实现对list的各种操作。这给使用者带来的方便,背后隐藏的是,经过严格的软件工程流程出厂的产品,在质量上的保证。所以在实际项目的开发中,下面的成员函数,还是建立感情吧。

assign() 给list赋值
back() 返回最后一个元素
clear() 删除所有元素
empty() 如果list是空的则返回true
end() 返回末尾的迭代器
erase() 删除一个元素
front() 返回第一个元素
get_allocator() 返回list的配置器
insert() 插入一个元素到list中
max_size() 返回list能容纳的最大元素数量
merge() 合并两个list
pop_back() 删除最后一个元素
pop_front() 删除第一个元素
push_back() 在list的末尾添加一个元素
push_front() 在list的头部添加一个元素
rbegin() 返回指向第一个元素的逆向迭代器
remove() 从list删除元素
remove_if() 按指定条件删除元素
rend() 指向list末尾的逆向迭代器
resize() 改变list的大小
reverse() 把list的元素倒转
size() 返回list中的元素个数
sort() 给list排序
splice() 合并两个list
swap() 交换两个list
unique() 删除list中重复的元素

有了STL,学数据结构做甚么?

  哦,原来STL这么好,数据的存储结构定义成了类,其中的基本操作和常用功能也用成员函数实现,知道接口,一切搞定,分分钟的事。
  可以,问题来了。有这么方便的“基础设施”,花功夫学数据结构课干什么?
  第一,作为专业人员,你可能会做“底层”工作,开发出比STL更好的东东,这个理想可以有,这个需求一直在;
  第二,只会套接口读手册写代码的,是码奴,知道其内部道道,才能够对现在的库驾驭自如,才能使用好基础设施,生产出真正高质量的产品。这里说的知道,不是入微到每一行代码都明了,而是对其内部的原理“有感觉”,这是专业人员应该具备的。给内行用的东西,你要成为内行。
  第三,再全的的工具,总有疏漏,当遇到一个需求,基础设施中没有时,只能自己造。没有数据结构功底,找别人造吧。找别人容易,但问题是,关键时候你就撤,撤哪儿去呢?
  第四,数据结构是专业功底,不只是用来干活的,还是指导思维的。即使只说动手能力,到底是hand最重要,还是brain更重要,不言自明。

  在知其然知其所以然的路上,奋进吧。基础的数据结构,实用的STL,都可以有。

  恰在刚才,一位同学在答疑区说“内容太多太复杂”。我回答:“有什么办法?人生来就是要奋斗的。”当跨过了这座山,回头却只是个小山丘,因为你已经身处高处。

猜你喜欢

转载自www.linuxidc.com/Linux/2015-09/123318.htm