stl:标准模板库
stl包括两方面:容器和算法
容器:是一种装数据的类型
算法:独立于特定的数据之外的某种通用算法
stl实际上就是将常用的数据类型或算法构造一些通用模板。
使用stl的优点:减少代码量,使代码的复用率大大提高,减轻了程序员的负担。
使用容器的优点:当自己写一个链表、队列、数组时,既要花时间还要操心去维护,怕里面的内存不够或长度太短问题,使用容器就能解决这种问题,它将这些数据结构都封装成了一个类,加上头文件就能使用,指针被封装成了迭代器,用起来更方便。
容器包括:顺序存储结构(vector list deque)、关联存储结构(set map multiset multimap)
下面我介绍一下常用的几个容器:
1.vector
连续存储结构,优点是查询更方便,相当于一个数组,但它支持不指定vector大小的存储,空间利用的灵活性
2.deque
连续存储结构,类似vector,它提供的是两级数组结构,第一级代表实际容器,另一级维护容器的首位地址,因此
他还多了一个支持高效的首尾插入删除操作。
它也叫双端队列,结合了vector和list的功能。
优点:(1)随机访问方便,支持[]和list的功能。
(2)在内部方便进行插入和删除
(3)可在两端push和pop
缺点:占用内存多
3.list
非连续存储结构,具有双链表结构
优点:
(1)不使用连续内存完成动态操作
(2)在内部方便的进行插入和删除
(3)在两端进行push和pop
缺点:
(1)不能进行内部的随机访问,不支持[]和vector. at()
(2)相对vector占用内存多
我们用的较多的是vector
下面我实现了list内部的部分功能(双向链表)
实现过程:
定义节点:节点包括数据,next指针,prev指针
#include <iostream>
#include <cstdlib>
using namespace std;
template <typename T>
class mlist
{
//节点的描述
struct Node
{
T data;
struct Node *next; //指向下一个节点
struct Node *prev; //指向前一个节点
// 构造函数
Node(T _data= 0) : data(_data)
{
next= NULL;
prev= NULL;
}
};
public:
/*迭代器无非是将节点再包裹一次*/
class iterator{
private:
Node *curr;//这个就是被包裹的那个节点
public:
/*构造函数*/
iterator(Node *node):curr(node){}
/* 运算符*号的重载,是将包裹打开,取出里面的数据 */
T& operator*(void)
{
return curr->data;
}
/* 运算符后++的重载*/
T& operator++(int)
{
Node *temp=curr;//先保存
curr=curr->next;//再移动
return temp->data;
}
/*运算符!=的重载*/
bool operator!=(const iterator &_itr)
{
if(this->curr!=_itr.curr)
return true;
else
return false;
}
};
private:
Node *head; //链表头
Node *tail; //链表尾
public:
/*构造函数*/
mlist(void)
{
/*给head和tail分配空间*/
head=new Node;
tail=new Node;
/*head和tail链接起来*/
head->next=tail;
tail->prev=head;
}
/*析构*/
~mlist(void)
{
while(head->next!=tail)
{
Node *temp=head->next->next;//保存要删除节点的下一个节点
delete head->next;
head->next=temp;
temp->prev=head;
}
delete head;
delete tail;
}
/*push_back函数*/
void push_back(T _data)
{
/*1 将数据包裹为一个节点*/
Node *pnew=new Node(_data);//malloc开辟,然后用构造函数初始化
/*2 将节点加到链表尾部*/
pnew->prev=tail->prev;
pnew->next=tail;
tail->prev->next=pnew;
tail->prev=pnew;
}
/*begin函数*/
iterator begin(void)
{
return iterator(head->next);
}
/*end函数*/
iterator end(void)
{
return iterator(tail);
}
/*测试*/
void printlist(void)
{
Node *temp=head->next;
while(temp!=tail)
{
cout<<temp->data<<'\t';
temp=temp->next;
}
cout<<endl;
}
};
int main(void)
{
mlist<int> m;
m.push_back(2017);
m.push_back(2018);
m.push_back(2020);
m.printlist();
mlist<int>::iterator itr=m.begin();
for(;itr!=m.end();itr++)
cout<<*itr<<'\t';
cout<<endl;
}