list<int> iNum
iNum.push_back(1);
iNum.push_front(3);//头插法
即用迭代器的方式进行遍历
- list<int>::iterator iter;
- for(iter=iNum.begin();iter!=iNum.end();iter++)
- {
- cout<<*iter<<" ";
- }
(可以从头部读一个删一个,也可以在尾部进行同样的操作,用back()访问元素&用pop_back进行删除)
- while(!iNum.empty())
- {
- cout<<iNum.front()<<" ";
- iNum.pop_front(); //头部删除
- }
函数原型:iterator find(iterator begin,iterator end,data);返回的是一个迭代器,用auto偷懒(
find没找的话,将返回end()所指向的位置。
- //函数原型:iterator find(iterator begin,iterator end,data);
- auto result=find(iNum.begin(),iNum.end(),2);
- //返回的是一个迭代器类型,此处是list<int>::iterator 类型
- //若没有找到,就是返回end结束的位置
- if(result==iNum.end())
- {
- cout<<"not find"<<endl;
- }
- iNum.insert(result,100);//该函数的作用是在result这个迭代器所指向的位置的前面插入100
insert()需要传入两个参数,一个是迭代器类型,一个是需要插入的数据。插入的位置是在迭代器所指向位置的前面进行插入,若需要在迭代器所指向位置后面进行插入,给这个迭代器位置+1即可。
会删除迭代器所指向的位置中的元素,然后原迭代器删除,返回一个新的迭代器,是指向原来所删除位置的下一个位置!!!(ps. 6.22终于理解了python列表的range()中的pop为什么删不干净了)
②区分三种写法(因为erase只能删除一个位置,所以此处需要删除所有指定的值)--"相同元素删除"
写法一(×):
- int array[4]={1,2,2,3};
- list<int>data;
- for(list<int>::iterator iter=data.begin();iter!=data.end();iter++)
- {
- if(*iter==2)
- {
- data.erase(iter);
- }
- }
报错:
原因:当前迭代器已经被删除了,它无法再去做++运算。
改进----
写法二(×):
- int array[4]={1,2,2,3};
- list<int>data;
- for(list<int>::iterator iter=data.begin();iter!=data.end();iter++)
- {
- if(*iter==2)
- {
- iter=data.erase(iter);
- }
- }
虽然不报错了。实际上iter在第一次被找到并按删除时,本身删完之后会++,在for里面也会++所以会跳过第一个2后面的2,于是会漏删一个。(删不干净)
写法三(√):正确写法。
- int array[4]={1,2,2,3};
- list<int>data;
- for(list<int>::iterator iter=data.begin();iter!=data.end();)
- {
- if(*iter==2)
- {
- iter=data.erase(iter);
- }
- else
- {
- iter++;
- }
-
- }
①reverse() 翻转链表函数。
②sort() 默认从小到大进行排序
- #include<functional>
- iNum.sort(less<int>());
- iNum.sort(greater<int>());
上面代码块中(需要包含头文件functional,less和greater都是类,()是里面被运算符重载过的)
第一行是从小到大进行排序 < -------less
第二行是从大到小进行排序 > -------greater
-------------以上:排序准则------------------
③swap() 交换
list是无参构造,不能定长。
需要注意的几个问题
①按照姓名进行查找find的写法(必须要自己写重载函数->需要按照什么查找就在重载函数里面按照该属性去实现。)
②按照age || name排序
i)重载写法(利用已有的比较准则)(需要按照哪一个属性进行重载,就写哪一个重载)
- mmDate.sort(less<int>());//需要重载<
- mmDate.sort(greater<int>());//需要重载>
ii)不采用重载方式,自己写比较准则
- //比较准则是一个函数指针,该函数的返回值是bool类型,两个参数
- bool compareByName(const MM&object1,const MM& object2)//比较准则
- {
- return object1.getName()<object2.getName();
- }
- mmDate.sort(compareByName);
操作自定义类型数据相关代码:
- //操作自定义类型数据
- class MM
- {
- public:
- MM(string name, int age, int num) :name(name), age(age), num(num) {}
- void print()
- {
- cout << name << "\t" << age << "\t" << num << endl;
- }
- bool operator==(const string& name) const
- {
- return this->name == name;
- }
- bool operator<(const MM& object) const
- {
- return this->name < object.name;
- }
- string getName() const
- {
- return name;
- }
- int getAge() const
- {
- return age;
- }
- protected:
- string name;
- int age;
- int num;
- };
- bool compareByName(const MM& object1, const MM& object2)
- {
- return object1.getName() < object2.getName();
- }
- bool compareByAge(const MM& object1, const MM& object2)
- {
- return object1.getAge() < object2.getAge();
- }
- void testUserData()
- {
- list<MM> mmData;
- string name;
- int age;
- int num;
- while (1)
- {
- cout << "input MM:" << endl;
- cin >> name >> age >> num;
- mmData.push_back(MM(name, age, num));
- cout << "是否继续输入?" << endl;
- while (cin.get() != '\n');
- if (cin.get() == 'n')
- break;
- }
- cout << "姓名\t年龄\t编号" << endl;
- for (MM v : mmData)
- {
- v.print();
- }
- //二进制“==”: 没有找到接受“MM”类型的左操作数的运算符(或没有可接受的转换)
- auto result = find(mmData.begin(), mmData.end(), "name1");
- //重载方式
- mmData.sort(less<MM>()); //重载<
- //mmData.sort(greater<MM>()); //重载>
- //不采用重载方式,需要自己写比较准则
- mmData.sort(compareByName);
- mmData.sort(compareByAge);
- }
注意:重载函数的写法与需求。
这一行,我们的目标是按照姓名进行查找name1对应的位置, 在MM类中需要写的重载函数中传入的参数应该是const string类型!!! 而非一个对象!!!
1.栈的相关原理:先进后出 注:无迭代器,是一个适配器
2.相关操作:
①push(data)
②pop(): 删除操作(无指定位置删除or插入)
③top() :获取栈顶元素
④size()和empty()
- #include <stack>
- #include <iostream>
- #include <string>
- using namespace std;
- void testStack()
- {
- //穿脱原则
- //FILO
- //1 2 3
- //3 2 1
- //push(data)
- //pop() 删除
- //top() 获取栈顶元素
- //size() empty();
- stack<int> intStack;
- for (int i = 0; i < 3; i++)
- {
- intStack.push(i);
- }
- while (!intStack.empty())
- {
- cout << intStack.top() << "\t";
- intStack.pop();
- }
- cout << endl;
- }
3.应用:①中缀表达式的转换;②将一个数字转成二进制(代码见下)
- void NumTobinary(int data)
- {
- stack<int> bin;
- while (data)
- {
- bin.push(data % 2);
- data = data / 2;
- }
- if (bin.size() < 8)
- {
- for (int i = bin.size(); i < 8; i++)
- {
- bin.push(0);
- }
- }
- while (!bin.empty())
- {
- cout << bin.top();
- bin.pop();
- }
- cout << endl;
- //中缀和后缀表达式资料看看
- //a+b 中缀
- //ab+
- //a+b*c+d;
- }
(即可代表栈,也可以代表队列)->用双向链表也可以描述这一操作
1.插入操作同list(①尾插法②头插法)
- deque<int> deData;
- for (int i = 0; i < 3; i++)
- {
- deData.push_back(i); //尾插法入队
- deData.push_front(i); //头插法入队
- }
2.此队列既可以从头部出来,也可以从尾部出来
①从头出来
- //从头出来
- void pop_front_dequeue(deque<int> dData)
- {
- while (!dData.empty())
- {
- cout << dData.front()<<" ";
- dData.pop_front();
- }
- cout << endl;
- }
②从尾部出来
- //从尾出来
- void pop_back_dequeue(deque<int> dData)
- {
- while (!dData.empty())
- {
- cout << dData.back() << " ";
- dData.pop_back();
- }
- cout << endl;
- }
双向队列用的较多(速度更快)
1.原理:先进先出
2.入队:push(data)
3.获取队头元素: front()
4.出队:pop()
(注:若不想删除原容器改动,那么就函数传参生成拷贝本操作即可。)
5.应用:层次遍历二叉树BFS(广度优先搜索)
1.头文件可以写以下两个之一
- #include<concurrent_priority_queue.h>
- #include<queue>
2.原理:需要另外一个容器充当容量(常用vector当做容器(无需传参数),array还需要传参数)
(原型:第一个参数是存储的数据类型,第二个参数是容器(中间的那个=号是缺省值),第三个参数是排序准则,第四个个参数是类名)
- template <class _Ty,class _Container = vector<_Ty>,class _Pr = less<_Ty>>
- class my_priority_queue
- {
- public:
-
- protected:
-
- };
按照特定的方式进行出队(按照数据的优先权出队)其实就是排好序再出队。
3.创建优先队列的三种方式:
- //默认的方式,一级下面三种 都一样,大的先出队
- priority_queue<int> pqData;
- priority_queue<int,vector<int>> pqData2; //默认排序准则
- priority_queue<int,vector<int>,less<int>> pqData3; //所有参数都完整
4.入队:push()
- pqData.push(12);
- pqData.push(0);
- pqData.push(34);
5.出队是默认从大到小(大的先出队)->default: less<int> (区别sort)
- priority_queue<int> pqData;
- while (!pqData.empty())
- {
- cout << pqData.top()<<" ";
- pqData.pop(); //出队
- }
若想让小的先出队 排序准则传参为 greater<int>
- priority_queue<int, vector<int>, greater<int>> pqDataG;
- pqDataG.push(12);
- pqDataG.push(0);
- pqDataG.push(34);
- while (!pqDataG.empty())
- {
- cout << pqDataG.top() << " ";
- pqDataG.pop(); //出队
- }
6.应用:贪心算法、Huffman树