list 的基本概念
list 链表,是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。
链表的功能:将数据进行链式存储。
链表的组成:链表由一系列结点组成。
链表的节点由两部分组成:
STL中的 list 是一个双向循环链表。
由于链表的存储方式并不是连续的内存空间,因此链表list 中的迭代器只支持前移和后移,属于双向迭代器
list 的优点:
- 采用动态存储分配,不会造成内存浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
- 插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的(STL中list和vector是两个最常被使用的容器,各有优缺点)
list 的缺点:
- 链表灵活,但是空间(指针域) 和 时间(遍历)额外耗费较大
构造函数
功能描述:
函数原型:
list<T> lst; //list采用采用模板类实现,对象的默认构造形式:list(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。list(n,elem); //构造函数将n个elem拷贝给本身。list(const list &lst); //拷贝构造函数。
#include<iostream>
#include<string>
#include<list>
using namespace std;
void print_list1(const list<int>& mylist) {
for (list<int>::const_iterator ite = mylist.begin(); ite != mylist.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
}
int main() {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
print_list1(list1);
list<int> list2(list1.begin(),list1.end());
print_list1(list2);
list<int> list3(5, 888);
print_list1(list3);
list<int> list4(list3);
print_list1(list4);
return 0;
}
赋值和交换
功能描述:
函数原型:
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。assign(n, elem); //将n个elem拷贝赋值给本身。list& operator=(const list &lst); //重载等号操作符swap(lst); //将lst与本身的元素互换。
#include<iostream>
#include<string>
#include<list>
using namespace std;
void print_list2(const list<int>& mylist) {
for (list<int>::const_iterator ite = mylist.begin(); ite != mylist.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
}
int main() {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
print_list2(list1);
list<int> list2;
list2.assign(list1.begin(), list1.end());
print_list2(list2);
list<int> list3;
list3.assign(5,9);
print_list2(list3);
list<int> list4 = list3;
print_list2(list4);
list1.swap(list4);
print_list2(list1);
print_list2(list4);
return 0;
}
大小操作
功能描述:
函数原型:
-
size(); //返回容器中元素的个数 -
empty(); //判断容器是否为空 -
resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。 ? //如果容器变短,则末尾超出容器长度的元素被删除。 -
resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
#include<iostream>
#include<string>
#include<list>
using namespace std;
void print_list3(const list<int>& mylist) {
for (list<int>::const_iterator ite = mylist.begin(); ite != mylist.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
}
int main() {
list<int>list1;
for (int i = 0; i < 10; i++) {
list1.push_back(i*i+1);
}
print_list3(list1);
cout << (list1.empty() ? "为空" : "不为空" )<< endl;
cout << "list1的大小:" << list1.size() << endl;
list1.resize(15);
print_list3(list1);
list1.resize(20,1);
print_list3(list1);
list1.resize(5);
print_list3(list1);
return 0;
}
插入和删除
功能描述:
函数原型:
push_back(elem); //在容器尾部加入一个元素pop_back(); //删除容器中最后一个元素push_front(elem); //在容器开头插入一个元素pop_front(); //从容器开头移除第一个元素insert(pos,elem); //在pos位置插elem元素的拷贝,返回新数据的位置。- i
nsert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。 insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值。clear(); //移除容器的所有数据erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。erase(pos); //删除pos位置的数据,返回下一个数据的位置。remove(elem); //删除容器中所有与elem值匹配的元素。
#include<iostream>
#include<string>
#include<list>
using namespace std;
void print_list4(const list<int>& mylist) {
for (list<int>::const_iterator ite = mylist.begin(); ite != mylist.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
}
int main() {
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_front(3);
mylist.push_front(4);
print_list4(mylist);
list<int>list2;
list2.push_back(11);
list2.push_back(22);
list2.push_back(33);
print_list4(list2);
list<int>::iterator p = mylist.begin();
mylist.insert(p++, 888);
print_list4(mylist);
mylist.insert(p++, 999);
print_list4(mylist);
mylist.insert(p,2, 777);
print_list4(mylist);
mylist.insert(p, list2.begin(), list2.end());
print_list4(mylist);
list2.erase(list2.begin(), list2.end());
cout << list2.size() << endl;
list<int>::iterator p_next = mylist.erase(p);
print_list4(mylist);
cout << "下一个元素是:" << *p_next << endl;
mylist.remove(777);
print_list4(mylist);
mylist.clear();
cout << mylist.size() << endl;
return 0;
}
数据存取
功能描述:
函数原型:
front(); //返回第一个元素。back(); //返回最后一个元素。
list的双向迭代器 双向迭代器,不支持随机访问,只能以递增或递减的方式逐步向前或者向后访问。
#include<iostream>
#include<string>
#include<list>
using namespace std;
void print_list5(const list<int>& mylist) {
for (list<int>::const_iterator ite = mylist.begin(); ite != mylist.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
}
int main() {
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_front(3);
mylist.push_front(4);
print_list5(mylist);
int first = mylist.front();
int last = mylist.back();
cout << first << endl;
cout << last << endl;
list<int>::iterator p = mylist.begin();
p++;
cout << *p << endl;
p--;
cout << *p << endl;
return 0;
}
反转和排序
功能描述:
函数原型:
reverse(); //反转链表sort(); //链表排序
#include<iostream>
#include<string>
#include<list>
using namespace std;
void print_list6(const list<int>& mylist) {
for (list<int>::const_iterator ite = mylist.begin(); ite != mylist.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
}
int main() {
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
mylist.push_back(4);
mylist.push_back(5);
mylist.push_back(6);
print_list6(mylist);
mylist.reverse();
print_list6(mylist);
mylist.clear();
srand((unsigned int)time(NULL));
for (int i = 0; i < 10; i++) {
int n = (rand() % (99 - 21 + 1)) + 21;
mylist.push_back(n);
}
print_list6(mylist);
mylist.sort();
print_list6(mylist);
return 0;
}
排序案例
案例需求:
- 创建一个 Person 类,成员变量:姓名、身高、体重
- 将多个 Pseron 对象存入list容器
- 根据 Person 的身高(先)、体重(后)进行升序排序
#include<iostream>
#include<string>
#include<list>
using namespace std;
void print_list7(const list<int>& mylist) {
for (list<int>::const_iterator ite = mylist.begin(); ite != mylist.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
}
class Person {
public:
string name;
int height;
int weight;
Person(string name,int weight,int height) {
this->name = name;
this->weight = weight;
this->height = height;
}
};
bool person_conmare(Person& p1, Person& p2) {
if (p1.height == p2.height) {
return p1.weight <= p2.weight;
}
else {
return p1.height <= p2.height;
}
}
ostream& operator<<(ostream& out, const Person& person) {
out << "姓名:" << person.name << " 身高:" << person.height << " 体重:" << person.weight;
return out;
}
string operator+(string& content, int number) {
string temp = "";
char t = 0;
while (true) {
t = number % 10 + '0';
temp = t + temp;
number /= 10;
if (number == 0) {
return content + temp;
}
}
}
string& operator+=(string& content, int number) {
return content = content + number;
}
void print_list7(list<Person>& mylist) {
for (list<Person>::const_iterator p = mylist.begin(); p != mylist.end(); p++) {
cout << *p << endl;
}
}
int main() {
srand((unsigned int)time(NULL));
list<Person> ps;
for (int i = 0; i < 10; i++) {
int h = (rand() % (170 - 150 + 1)) + 150;
int w = (rand() % (70 - 50 + 1)) + 50;
string name = "Person-";
name += i;
Person p(name, w, h);
ps.push_back(p);
}
print_list7(ps);
cout << "***********" << endl;
ps.sort(person_conmare);
print_list7(ps);
}
姓名:Person-0 身高:165 体重:60
姓名:Person-1 身高:161 体重:56
姓名:Person-2 身高:159 体重:64
姓名:Person-3 身高:163 体重:55
姓名:Person-4 身高:157 体重:52
姓名:Person-5 身高:155 体重:64
姓名:Person-6 身高:165 体重:69
姓名:Person-7 身高:169 体重:65
姓名:Person-8 身高:168 体重:56
姓名:Person-9 身高:167 体重:50
***********
姓名:Person-5 身高:155 体重:64
姓名:Person-4 身高:157 体重:52
姓名:Person-2 身高:159 体重:64
姓名:Person-1 身高:161 体重:56
姓名:Person-3 身高:163 体重:55
姓名:Person-0 身高:165 体重:60
姓名:Person-6 身高:165 体重:69
姓名:Person-9 身高:167 体重:50
姓名:Person-8 身高:168 体重:56
姓名:Person-7 身高:169 体重:65
|