版权声明:本博客为博主原创文章,未经博主允许,禁止转载,谢谢合作。 https://blog.csdn.net/weixin_43971252/article/details/88527491
list容器是循环双链表,因为存储空间不连续,所以他的迭代器不支持随机访问,进行排序时不能使用algorithm 里的sort,使用list自身的成员函数sort进行排序.
#include<iostream>
#include<list>
#include<string>
using namespace std;
//list是一个双向循环链表,list迭代器不支持随机访问
void printList(list<int>& l, string s) {
if (l.empty())
{
cout << "list is empty!" << endl;
return;
}
cout << "list elem : ";
if (s.compare("正序输出") == 0) {
for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
cout << *it << " ";
}
else {
for (list<int>::reverse_iterator r_it = l.rbegin(); r_it != l.rend(); r_it++)
cout << *r_it << " ";
}
cout << endl;
}
//初始化和赋值
void test_one() {
list<int> mylist1{ 1,2,3,5,6,2 }; //构造方法1
cout << "list front : " << mylist1.front() << endl; //获取头部元素
cout << "list back : " << mylist1.back() << endl; //获取尾部元素
printList(mylist1, "正序输出");
printList(mylist1, "逆序输出");
mylist1.reverse(); //将list容器内的元素倒转
printList(mylist1, "正序输出");
mylist1 = list<int>(3, 100); //赋值,会重新分配list容器的内存,参数(n,elem)
cout << "mylist1 size: " << mylist1.size()<<endl;
printList(mylist1, "正序输出");
//list<int> mylist2(mylist1); //ok
list<int> mylist2 = mylist1; //构造方法2:重载 =或()
printList(mylist2, "正序输出");
list<int> mylist3(mylist1.begin(), mylist1.end()); //构造方法3:区间元素来构造,参数为迭代器
printList(mylist3, "正序输出");
//resize 重新指定大小,如果容器大小变短,舍弃多余的,并且不改变以前对应位置的元素值,若变长,则将变长的部分赋值为0或指定的数值
mylist3.resize(mylist3.size() - 2, 666);
printList(mylist3, "正序输出");
mylist3.resize(mylist3.size() + 2, 666);
printList(mylist3, "正序输出");
//assign 向容器里重新写入数据
int arr[3]{ 555,666,777 };
mylist3.assign(10,-1); //(n,elem):容器里重写n个elem
printList(mylist3, "正序输出");
mylist3.assign(arr, arr + 3); //(start,end):将[start,end) 左闭右开的区间内的数据写入容器
printList(mylist3, "正序输出");
mylist3.swap(mylist1); //swap交换两个list容器
printList(mylist3, "正序输出");
}
//插入和删除
void test_two() {
list<int> list1;
list1.push_back(100); //尾部插入
list1.emplace_back(200);
list1.push_front(0); //头部插入
list1.emplace_front(-100);
printList(list1, "正序输出");
list1.pop_back(); //尾删
list1.pop_front(); //头删
printList(list1, "正序输出");
//指定位置插入
list1.insert(list1.begin(), 222); //1.(pos,value) :pos为迭代器指向的位置
printList(list1, "正序输出");
list1.insert(list1.end(), 3, 666); //2.(pos,count,value)
printList(list1, "正序输出");
int arr[3]{ 8,9,10 };
//list1.insert(list1.begin() + list1.size(), arr, arr + 3); //error :因为list的空间不是连续的,其迭代器不支持随机访问,没有重载 +
list1.insert(list1.end(), arr, arr + 3); //3.(pos,start,end): 插入[start,end)左闭右开的区间内的元素
printList(list1, "正序输出");
list<int> list2(list1);
//指定位置删除
list1.erase(list1.begin()); //(pos)
printList(list1, "正序输出");
list1.erase(list1.begin(), list1.end()); //(start,end): 删除[start,end)区间的元素 ,如果参数为迭代器的起始位置就等价于clear()
printList(list1, "正序输出");
//指定数据删除
list2.push_back(30);
list2.push_front(30);
list2.insert(list2.begin(), 3, 30);
printList(list2, "正序输出");
list2.remove(30); //(elem) :删除链表中与elem相同的所有元素
printList(list2, "正序输出");
}
//排序
//list的迭代器不是随机访问的迭代器,所以不能使用系统的sort,得使用它自己的成员函数
bool myCompare(int a, int b) { return a > b; }
void test_three() {
list<int> l{ 1,2,6,-3,-6 };
printList(l, "正序输出");
l.sort(); //默认是升序排序
printList(l, "正序输出");
l.sort(myCompare); //使用回调函数自定义排序规则
printList(l, "正序输出");
}
//自定义数据类型排序和删除
//排序时:必须写回调函数来定义排序规则
//删除时:要在类的内部重载==
class myclass {
public:
myclass(string name, int age) {
m_name = name;
m_age = age;
}
//重载 == 实现删除对象
bool operator==(const myclass& p) {
if (this->m_age == p.m_age && this->m_name == p.m_name)
return true;
else
return false;
}
public:
string m_name;
int m_age;
};
void printMyclass(list<myclass>& myl) {
for (list<myclass>::const_iterator it = myl.begin(); it != myl.end(); it++)
cout << "name : " << it->m_name << " age : " << it->m_age << endl;
cout << "\n";
}
//按年龄进行升序排序
bool myCompareClass(myclass& a, myclass& b) {
return a.m_age < b.m_age ? true : false;
}
void test_four() {
list<myclass> mylist;
myclass c1{ "张三",20 };
myclass c2{ "李四",21 };
myclass c3{ "王二",18 };
myclass c4{ "麻子",16 };
mylist.emplace_back(c1);
mylist.emplace_back(c2);
mylist.emplace_back(c3);
mylist.emplace_back(c4);
printMyclass(mylist);
mylist.sort(myCompareClass);
printMyclass(mylist);
mylist.remove(c4); //传递要删除的对象
printMyclass(mylist);
}
int main()
{
//test_one();
//test_two();
//test_three();
test_four();
cin.get();
return 0;
}
补充:合并两个链表可使用merge和splice.