STL入门与简介
#include<iostream>
#include <vector>//容器
#include<array>//数组
#include <algorithm>//算法
using namespace std;
//实现一个类模板,专门实现打印的功能
template<class T> //类模板实现了方法
class myvectorprint
{
public:
void operator ()(const T &t)//重载,使用(),打印
{
std::cout << t << std::endl;
}
};
void main()
{
vector<int> myvector;
myvector.push_back(11);
myvector.push_back(21);
myvector.push_back(31);
myvector.push_back(81);
myvector.push_back(51);
array<int, 10> myarray = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
myvectorprint<int >print;//对于打印进行实例化
//begin,endl迭代器,是一个指针
for_each (myvector.begin(), myvector.end(),print);
for_each(myarray.begin(), myarray.end(), print);
cin.get();
//算法可以适用于任何容器,for_each是一个算法
}
STL容器概念
数组线性容器
#include<iostream>
#include<vector>
#include <array>
#include <tuple>
using namespace std;
void main1()
{
array<int, 5>myarray = { 1, 2, 3, 4, 5 };
//数组,静态数组,栈上
vector <int >myvetor;
myvetor.push_back(1);
//动态数组,堆上,
//不需要变长,容量较小,array
//需要变长,容量较大,vetor
}
链式容器
#include<iostream>
#include <hash_set>
#include <list>
#include<stdio.h>
//list适用于经常插入,经常删除
using namespace std;
void main()
{
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
mylist.push_back(4);
//mylist[1];
auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist.end();
//list用迭代器进行遍历
for (;ibegin!=iend;ibegin++)
{
cout << *ibegin << endl;
printf("%p,%p\n", ibegin._Ptr,ibegin);//重载
}
cin.get();
}
//list删除
void main3()
{
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
mylist.push_back(4);
mylist.push_back(5);
//auto i = mylist.begin();//删除元素,依赖于迭代器,
//++i;
//++i;
//++i;
auto i = mylist.end();//end最后一个没有实体,
//
i--;
mylist.erase(i);//链式存储,不允许下标访问
//只能用迭代器,链表迭代器只能用++,--
//mylist.clear();清空
auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist.end();
for (; ibegin != iend; ibegin++)
{
if ((*ibegin) == 3)
{
mylist.erase(ibegin);//删除,删除的时候迭代器会发生
break;
}
//cout << *ibegin << endl;
}
{
auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist.end();
for (; ibegin != iend; ibegin++)
{
cout << *ibegin << endl;
}
}
cin.get();
}
void main4()
{
int a[5] = { 1, 2, 3, 4, 5 };
list<int > mylist(a, a + 5);//根据数组初始化,
//传递开始地址,传递结束地址
// mylist(0);
//mylist[1];只能用迭代器访问
mylist.push_back(10);
mylist.push_front(12);
auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist.end();
for (; ibegin != iend; ibegin++)
{
if (*ibegin==3)
{
mylist.insert(ibegin ,30);
break;//删除或者插入,迭代器都会发生变化
}
}
mylist.remove(30);//直接一个函数,根据元素来删除
{
auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist.end();
for (; ibegin != iend; ibegin++)
{
cout << *ibegin << endl;
}
}
cin.get();
}
void main5()
{
int a[5] = { 1, 2, 3, 4, 5 };
list<int > mylist(a, a + 5);//根据数组初始化,
auto rb = mylist.rbegin();
auto re = mylist.rend();
//同时正向与方向查找
for (;rb != re; rb++)
{
cout << *rb << endl;
}
cin.get();
}
void main6()
{
int a[5] = { 1, 2, 3, 104, 5 };
list<int > mylist1(a, a + 5);//根据数组初始化,
int b[5] = { 11, 122,33, 44, 55 };
list<int > mylist2(b, b + 5);//根据数组初始化,
mylist1.sort();
mylist2.sort();//排序
mylist1.merge(mylist2);//合并之前必须有序
{
auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist1.end();
for (; ibegin != iend; ibegin++)
{
cout << *ibegin << endl;
}
}
cout << "\n\n\n";
{
auto ibegin = mylist2.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist2.end();
for (; ibegin != iend; ibegin++)
{
cout << *ibegin << endl;
}
}
cin.get();
}
void main7()
{
int a[6] = { 1, 2,98, 2, 5, 98 };
list<int > mylist1(a, a + 6);//根据数组初始化,
{
auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist1.end();
for (; ibegin != iend; ibegin++)
{
cout << *ibegin << endl;
}
}
mylist1.sort();
mylist1.unique();//唯一依赖于排序
cout << "\n\n\n";
{
auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist1.end();
for (; ibegin != iend; ibegin++)
{
cout << *ibegin << endl;
}
}
cin.get();
}
红黑树容器
#include<iostream>
#include <set>
using namespace std;
void main1231()
{
set<int>myset;
myset.insert(10);
myset.insert(9);
myset.insert(8);
myset.insert(7);
myset.insert(5);
myset.insert(6);
myset.insert(7);
//myset.insert(7);重复会被舍弃
auto findpos = myset.find(10);
cout << " find ->" << *findpos << " \n";
auto ib = myset.begin();
auto ie = myset.end();
for (;ib!=ie;ib++)
{
cout << *ib << " ";
}
std::cout << "\n"<<myset.size() << endl;
cin.get();
}
容器迭代器仿函数算法STL概念例子
算法的概念
#include <algorithm>
#include <iostream>
using namespace std;
struct print
{
void operator ()(int x)//重载了()符号,之际调用()
{
std::cout << x << endl;
}
};
void printA(int x)
{
std::cout << x << endl;
}
void main1()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *p = find(a, a + 10, 8);
std::cout << (void*)a << (void*)(a + 10) << std::endl;
std::cout << *p << endl;
std::cout << p << endl;
if (p==(a+10))
{
std::cout << "没有找到\n";
}
for_each(a, a + 4, print());//遍历每一个元素,
//printA是一个函数指针,必须是函数类型
cin.get();
}
容器与迭代器
#include<iostream>
#include <set>
#include <stdio.h>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void main12()
{
multiset <int>myset;
myset.insert(11);
myset.insert(12);
myset.insert(13);
myset.insert(10);
myset.insert(10);
myset.insert(100);
auto ib = myset.begin();
auto ie = myset.end();
for (;ib!=ie;ib++)
{
std::cout << *ib << std::endl;
printf("%p,%p\n", ib, ib._Ptr);//智能指针
}
cin.get();
}
void main()
{
list<int> mylist;
mylist.push_back(11);
mylist.push_back(1);
mylist.push_back(16);
mylist.push_back(1);
mylist.push_back(18);
auto ib = mylist.begin();
auto ie = mylist.end();
for (;ib!=ie;ib++)
{
std::cout << *ib << std::endl;
printf("%p\n", ib);
printf("%p\n", ib._Ptr);
//智能指针 STL bug ,分行打印,先访问内部,再访问外部
printf("%p,%p\n", ib._Ptr,ib );//智能指针.
}
cin.get();
}
void mainx()
{
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
mylist.push_back(4);
//mylist[1];
auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
auto iend = mylist.end();
//list用迭代器进行遍历
for (; ibegin != iend; ibegin++)
{
cout << *ibegin << endl;
printf("%p,%p\n", ibegin._Ptr, ibegin);//重载
}
cin.get();
}
bool less3(int x)
{
return x < 3;
}
void mainu()
{
vector<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(16);
mylist.push_back(1);
mylist.push_back(18);
using namespace std;
auto ib = mylist.begin();
auto ie = mylist.end();
for (; ib != ie; ib++)
{
std::cout << *ib << std::endl;
}
//仿函数可以实现一定的算法策略
//auto ifind = find_if(++mylist.begin(), mylist.end(), bind1st( greater<int>(), 3));
auto ifind = find_if(mylist.begin(), mylist.end(), less3);
// bind1st( greater<int>(), 3)
//绑定一个函数, greater<int>(),3
std::cout <<"\n\n\n\n"<< *ifind << endl;
cin.get();
}
栈队列双端队列优先队列
栈
#include <stack>
#include <iostream>
using namespace std;
void mainB()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
stack<int> mystack;
for (int i = 0; i < 10;i++)
{
mystack.push(a[i]);
}
while (!mystack.empty())
{
int num = mystack.top();
std::cout << num << " ";
mystack.pop();
}
cin.get();
}
void mainA()
{
int num;
cin >> num;
stack<int> mystack;
for ( ;num;num/=2)
{
mystack.push(num % 2);
std::cout << "当前元素个数" << mystack.size() << endl;
}
while (!mystack.empty())
{
int num=mystack.top();
std::cout << num << " ";
mystack.pop();
}
cin.get();
cin.get();
}
队列
#include <queue>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <list>
#include<deque>//双端队列
//提供了二维动态数组的功能,头部,尾部,任意操作
using namespace std;
void mainX()
{
queue<char *>myq;
myq.push("calc");
myq.push("notepad");
myq.push("tasklist");
myq.push("mspaint");
while (!myq.empty())
{
char *p= myq.front();//获取
system(p);
myq.pop();
}
}
void mainY()
{
deque<int> mydq;
mydq.push_back(1);
mydq.push_back(11);
mydq.push_back(111);
mydq.push_back(1111);
mydq.push_back(11111);
mydq.push_front(123);
mydq.insert(mydq.begin() + 3, 100);//插入
for (int i = 0; i < mydq.size();i++)
{
std::cout << mydq[i] << std::endl;
}
auto ib = mydq.begin();
auto ie = mydq.end();
for (; ib != ie; ib++)
{
std::cout << *ib<< std::endl;
}
cin.get();
}
void main11()
{
deque<int> mydq;
mydq.push_back(1);
mydq.push_back(11);
mydq.push_back(111);
mydq.push_back(1111);
mydq.push_back(11111);
mydq.push_front(123);
//mydq.erase(mydq.begin());
//mydq.erase(mydq.end() - 1);
mydq.pop_front();//头部弹出
mydq.pop_back();//尾部
//mydq.clear();
auto ib = mydq.begin();
auto ie = mydq.end();
for (; ib != ie; ib++)
{
std::cout << *ib << std::endl;
}
cin.get();
}
void main1234()
{
deque<int> mydq1;
mydq1.push_back(1);
mydq1.push_back(11);
mydq1.push_back(111);
mydq1.push_back(1111);
mydq1.push_back(11111);
deque<int> mydq2;
mydq2.push_back(2);
mydq2.push_back(21);
mydq2.push_back(211);
mydq2.push_back(2111);
mydq1.swap(mydq2);
//块语句
{
auto ib = mydq1.begin();
auto ie = mydq1.end();
for (; ib != ie; ib++)
{
std::cout << *ib << std::endl;
}
}
{
auto ib = mydq2.begin();
auto ie = mydq2.end();
for (; ib != ie; ib++)
{
std::cout << *ib << std::endl;
}
}
cin.get();
}
void mainXF()
{
deque<int> mydq1;
mydq1.push_back(1);
mydq1.push_back(11);
mydq1.push_back(111);
mydq1.push_back(1111);
mydq1.push_back(11111);
std::cout << mydq1.front() << std::endl;
std::cout << mydq1.back() << std::endl;
std::cout << mydq1.max_size() << std::endl;
std::cout << mydq1.size() << std::endl;
cin.get();
}
void mainRT()
{
priority_queue<int > myq;
myq.push(10);
myq.push(12);
myq.push(11);
myq.push(110);
myq.push(101);//自动排序
while (!myq.empty())
{
std::cout << myq.top() << endl;
myq.pop();
}
cin.get();
}
struct student
{
int age;
string name;
};
//strcmp==0; 字符串比较, c风格
struct stuless
{
//仿函数
bool operator()(const student &s1, const student &s2)
{
return s1.age < s2.age;
}
};
void main()
{ //类名, //存储 //比大小
priority_queue<student, deque<student>, stuless> myq;
student s1;
s1.age = 10;
s1.name = "谭胜";
student s2;
s2.age = 9;
s2.name = "熊飞";
student s3;
s3.age = 19;
s3.name = "熊peng飞";
myq.push(s1);
myq.push(s2);
myq.push(s3);
while (!myq.empty())
{
std::cout << myq.top().age << myq.top().name << endl;
myq.pop();
}
cin.get();
}
数据结构堆的概念
堆数据结构是一种数组对象,它可以被视为一科完全二叉树结构。它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。
数组的形式,采用顺序存储,构成树的结构。
红黑树容器
Set 每一个节点就是一个基本的节点数据
#include<iostream>
#include <set>
#include <string>
#include <bitset>
using namespace std;
struct strless
{
bool operator()(const char *str1, const char *str2) //二分查找法依赖于有序,字符串有序
{
return strcmp(str1, str2) < 0;
}
};
//红黑树,处理纯数字非常少,处理类对象以及字符串
void main1()
{
//set<char *, strless> myset(strless());//默认构造
const char *cmd[] = { "abc", "calc", "notepad", "const","xyz","ghj" };
set< const char *, strless> myset(cmd, cmd + 6, strless());//构造
myset.insert("1234");
myset.insert("4567");
//pair起到获取插入返回值,第一个类型,类型比大小的方式
pair<set<const char *>::iterator, bool> p = myset.insert("9876");
cout << "pair start" << endl;
cout << *(p.first) <<" "<< p.second << endl;
cout << "pair over" << endl;
auto ib = myset.begin();
auto ie = myset.end();
for (;ib!=ie;ib++)
{
cout << *ib << endl;
}
auto rb = myset.rbegin();
auto re = myset.rend();
for (; rb != re; rb++)
{
cout << *rb << endl;
}
set<const char *, strless>::iterator pfind = myset.find("xyz");//查找
std::cout <<"\n\n\n"<< *pfind << endl;
// std::cout << "\n\n\n" << *p << endl;
cin.get();
}
Multiset 内部机制:红黑树的每一个节点是链表
#define _CRT_SECURE_NO_WARNINGS
#include <set>
#include <iostream>
#include <string>
//mutiset每一个节点都是一个链表,set每个节点就是一个节点
using namespace std;
struct student
{
int id;
char name[30];
};
//排序
struct stuless
{
bool operator()(const student &s1, const student &s2)
{
return s1.id < s2.id;
}
};
void main2()
{
student sarray[3] = { { 10, "tansheng" }, { 3, "liguilong" }, { 4, "xiongfei" } };
multiset<student, stuless> myset (sarray, sarray + 3, stuless());
student stu1;
stu1.id = 20;
strcpy(stu1.name, "mouzhiwei");
myset.insert(stu1);
strcpy(stu1.name, "mouzhiwei1");
myset.insert(stu1);
strcpy(stu1.name, "mouzhiwei2");
myset.insert(stu1);
auto ib = myset.begin();
auto ie = myset.end();
for (;ib!=ie;ib++)
{
cout << (*ib).id << " " << (*ib).name << endl;
}
cin.get();
}
映射map 本质也是红黑树,可以同时存储很多数据。
#include <map>//也是红黑树
#include <iostream>
using namespace std;
void main1111()
{
map<const char * , int> mymap;
mymap["司令"] = 10;//映射 ,对等的映射查找
mymap["军长"] = 9;
mymap["师长"] = 8;
mymap["旅长"] = 7;
cout << mymap["司令"] << endl;
cout << mymap["军长"] << endl;
cout << mymap["师长"] << endl;
cout << mymap["旅长"] << endl;
std::cin.get();
}
struct student
{
char * name;
int year;
};
struct stuinfo
{
int id;
student stu;
};
void main3213()
{
stuinfo infoarrary[] = { { 10, { "yincheng1", 21 } },
{ 5, { "yincheng2", 22 } } ,
{ 25, { "yincheng3", 30 } } };
map<int, student> m;//编号映射 结构体
for (int i = 0; i < 3;i++)
{
m[ infoarrary[i].id ] = infoarrary[i].stu;//编号映射一个学生的信息
}
stuinfo infoarrarys = { 101, { "china", 99 } };
m[25] = infoarrarys.stu;//映射
map<int,student>::iterator ib = m.begin();
auto ie = m.end();
for (;ib!=ie;ib++)
{
cout << (*ib).first << endl;
cout << (*ib).second.name <<" " <<(*ib).second.year << endl;
}
cin.get();
}
Multimap 每一个节点又是一个链表
#include <map>
#include <iostream>
using namespace std;
//map,mutlimap区别是map每一个节点是一个映射
//multimap每一个一个节点是映射的链表的开头
void main121321()
{
map<const char *, int> m;
m.insert(pair<const char *, int>("司令1",101));
m.insert(pair<const char *, int>("司令2", 102));
m.insert(pair<const char *, int>("司令3", 103));
m.insert(pair<const char *, int>("司令1", 104));
map<const char *, int>::iterator ib = m.begin();
auto ie = m.end();
for (; ib != ie; ib++)
{
cout << (*ib).first << " " << (*ib).second << "\n";
}
cin.get();
}
void main2123123()
{
multimap<const char *, int> m;
m.insert(pair<const char *, int>("司令1", 101));
m.insert(pair<const char *, int>("司令2", 102));
m.insert(pair<const char *, int>("司令3", 103));
m.insert(pair<const char *, int>("司令1", 104));
auto ib = m.begin();
auto ie = m.end();
for (; ib != ie; ib++)
{
cout << (*ib).first << " " << (*ib).second << "\n";
}
cin.get();
}
Hash_set hash不需要排序,能够做到快速查找。秒查,比二分查找法还快。

#include <hash_set>
#include <iostream>
#include<algorithm>
#include <string>
using namespace std;
void main123123123()
{
const char *cmd[] = { "abc", "calc", "notepad", "const", "xyz", "ghj" };
hash_set<const char*> hs;//C++11自带了字符串的哈希
hs.insert("chian");
hs.insert("chi123an");
hs.insert("chi23an");
hs.insert("chzcian");
hs.insert("1chzcian");
auto pfind = hs.find("chi1213an");
if (pfind == hs.end())
{
std::cout << "没有";
}
else
{
std::cout << *pfind;
}
cin.get();
}
void main1asdasdsad()
{
hash_set<int> hs;
hs.insert(91);
hs.insert(21);
hs.insert(41);
auto ib = hs.begin();
auto ie = hs.end();
for (;ib!=ie;ib++)
{
cout << *ib << endl;
}
auto pfind = hs.find(211);
if (pfind==ie)
{
std::cout << "没有";
}
else
{
std::cout << *pfind;
}
cin.get();
}
Hash_map
#include <hash_map>//也是红黑树
#include <iostream>
#include<map>
using namespace std;
void main()
{
map< int,const char *> m;
m.insert(pair< int, const char *>(201, "司令1" ));
m.insert(pair< int, const char *>(101, "司" ));
m.insert(pair< int, const char *>(401, "司令11111" ));
m.insert(pair< int, const char *>(301, "司令"));
auto ib = m.begin();
auto ie = m.end();
for (; ib != ie; ib++)
{
cout << (*ib).first << " " << (*ib).second << "\n";
}
{
hash_map< int, const char *> m;
m.insert(pair< int, const char *>(201, "司令1"));
m.insert(pair< int, const char *>(101, "司"));
m.insert(pair< int, const char *>(401, "司令11111"));
m.insert(pair< int, const char *>(301, "司令"));
auto ib = m.begin();
auto ie = m.end();
for (; ib != ie; ib++)
{
cout << (*ib).first << " " << (*ib).second << "\n";
}
auto tofind = m.find(1101);
if (tofind == ie)
{
cout << "没有找到";
}
else
{
cout << "\n\n\n"<<(*tofind).first<<" "<<(*tofind).second;
}
}
std::cin.get();
}