C++ Development of Generic Programming Lecture 8 [list container]

1. Basic concepts

The list container is the linked list in our data structure, which is a non-continuous storage structure on a physical storage unit.

The logical sequence of data elements is realized by pointer links in the linked list.

Linked list: the list consists of a series junction composed of

The composition of the node: one is the data field that stores the data element , and the other is the pointer field that stores the address of the next node

The linked list in STL is a two-way circular linked list

Because the storage method of the linked list is not a continuous memory space, the iterator in the linked list list only supports forward and backward movement, which is a two-way iterator

Advantages of list:

  • Using dynamic storage allocation, will not cause memory waste and overflow
  • It is very convenient to perform insert and delete operations in the linked list. You can modify the pointer without moving a large number of elements.

Disadvantages of list:

  • Linked list is flexible, but space (pointer field) and time (traversal) are extra expensive

List has an important property, insertion operation and deletion operation will not cause the invalidation of the original list iterator, which is not true in vector.

Summary: List and vector in STL are the two most commonly used containers , each with its own advantages and disadvantages.

 

Second, the constructor

Function description:

  • Create list container

Function prototype:

  • list<T> lst; //list is implemented using template classes, and the default structure of the object:
  • list(beg,end); //The constructor copies the elements in the [beg, end) range to itself.
  • list(n,elem); //The constructor copies n elems to itself.
  • list(const list &lst); //Copy constructor.

Example:

#include <list>

void printList(const list<int>& L) {

	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

void test01()
{
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	printList(L1);

	list<int>L2(L1.begin(),L1.end());
	printList(L2);

	list<int>L3(L2);
	printList(L3);

	list<int>L4(10, 1000);
	printList(L4);
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary: The list construction method is the same as that of several other STL commonly used containers.

Three, assignment and exchange

Function description:

  • Assign values ​​to the list container, and exchange the list container

Function prototype:

  • assign(beg, end); // Assign a copy of the data in the interval [beg, end) to itself.
  • assign(n, elem); //Assign n copies of elem to itself.
  • list& operator=(const list &lst); //Overload the equal sign operator
  • swap(lst); //Swap lst with its own elements.

Example:

#include <list>

void printList(const list<int>& L) {

	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

//赋值和交换
void test01()
{
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);
	printList(L1);

	//赋值
	list<int>L2;
	L2 = L1;
	printList(L2);

	list<int>L3;
	L3.assign(L2.begin(), L2.end());
	printList(L3);

	list<int>L4;
	L4.assign(10, 100);
	printList(L4);

}

//交换
void test02()
{

	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	list<int>L2;
	L2.assign(10, 100);

	cout << "交换前: " << endl;
	printList(L1);
	printList(L2);

	cout << endl;

	L1.swap(L2);

	cout << "交换后: " << endl;
	printList(L1);
	printList(L2);

}

int main() {

	//test01();

	test02();

	system("pause");

	return 0;
}

Summary: The list assignment and exchange operations can be used flexibly

Four, size operation

Function description:

  • Operate on the size of the list container

Function prototype:

  • size(); //Returns the number of elements in the container

  • empty(); //Determine whether the container is empty

  • resize(num); //Re-specify the length of the container as num. If the container becomes longer, the new position will be filled with the default value.

    ​ //If the container becomes shorter, the elements at the end that exceed the length of the container are deleted.

  • resize(num, elem); //Re-specify the length of the container as num. If the container becomes longer, fill the new position with the elem value.

  • If the container becomes shorter, the elements at the end that exceed the length of the container are deleted.

Example:

#include <list>

void printList(const list<int>& L) {

	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

//大小操作
void test01()
{
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	if (L1.empty())
	{
		cout << "L1为空" << endl;
	}
	else
	{
		cout << "L1不为空" << endl;
		cout << "L1的大小为: " << L1.size() << endl;
	}

	//重新指定大小
	L1.resize(10);
	printList(L1);

	L1.resize(2);
	printList(L1);
}

int main() {

	test01();

	system("pause");

	return 0;
}

to sum up:

  • Determine whether it is empty — empty
  • Returns the number of elements — size
  • Re-specify the number — resize

Five, insert and delete

Function description:

  • Insert and delete data to the list container

Function prototype:

  • push_back(elem);//Add an element to the end of the container
  • pop_back();//Delete the last element in the container
  • push_front(elem);//Insert an element at the beginning of the container
  • pop_front();//Remove the first element from the beginning of the container
  • insert(pos,elem);//Insert a copy of the elem element at the pos position and return the position of the new data.
  • insert(pos,n,elem);//Insert n elem data at position pos, no return value.
  • insert(pos,beg,end);//Insert the data in the [beg,end) interval at position pos, no return value.
  • clear();//Remove all data of the container
  • erase(beg,end);//Delete the data in the [beg,end) interval and return the position of the next data.
  • erase(pos);//Delete the data at the pos position and return the position of the next data.
  • remove(elem);//Delete all elements in the container that match the elem value.

Example:

#include <list>

void printList(const list<int>& L) {

	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

//插入和删除
void test01()
{
	list<int> L;
	//尾插
	L.push_back(10);
	L.push_back(20);
	L.push_back(30);
	//头插
	L.push_front(100);
	L.push_front(200);
	L.push_front(300);

	printList(L);

	//尾删
	L.pop_back();
	printList(L);

	//头删
	L.pop_front();
	printList(L);

	//插入
	list<int>::iterator it = L.begin();
	L.insert(++it, 1000);
	printList(L);

	//删除
	it = L.begin();
	L.erase(++it);
	printList(L);

	//移除
	L.push_back(10000);
	L.push_back(10000);
	L.push_back(10000);
	printList(L);
	L.remove(10000);
	printList(L);
    
    //清空
	L.clear();
	printList(L);
}

int main() {

	test01();

	system("pause");

	return 0;
}

to sum up:

  • End plug — push_back
  • Tail delete — pop_back
  • Head plug — push_front
  • Head delete — pop_front
  • Insert — insert
  • Delete — erase
  • Remove — remove
  • Clear — clear

Six, data access

Function description:

  • Access the data in the list container

Function prototype:

  • front(); //Return the first element.
  • back(); //Return to the last element.

Example:

#include <list>

//数据存取
void test01()
{
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	
	//cout << L1.at(0) << endl;//错误 不支持at访问数据
	//cout << L1[0] << endl; //错误  不支持[]方式访问数据
	cout << "第一个元素为: " << L1.front() << endl;
	cout << "最后一个元素为: " << L1.back() << endl;

	//list容器的迭代器是双向迭代器,不支持随机访问
	list<int>::iterator it = L1.begin();
	//it = it + 1;//错误,不可以跳跃访问,即使是+1
}

int main() {

	test01();

	system("pause");

	return 0;
}

to sum up:

  • Data cannot be accessed in the list container through [] or at
  • Return the first element — front
  • Back to the last element — back

Seven, reverse and sort

Function description:

  • Reverse the elements in the container and sort the data in the container

Function prototype:

  • reverse(); //Reverse linked list
  • sort(); //Linked list sort

Example:

void printList(const list<int>& L) {

	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

bool myCompare(int val1 , int val2)
{
	return val1 > val2;
}

//反转和排序
void test01()
{
	list<int> L;
	L.push_back(90);
	L.push_back(30);
	L.push_back(20);
	L.push_back(70);
	printList(L);

	//反转容器的元素
	L.reverse();
	printList(L);

	//排序
	L.sort(); //默认的排序规则 从小到大
	printList(L);

	L.sort(myCompare); //指定规则,从大到小
	printList(L);
}

int main() {

	test01();

	system("pause");

	return 0;
}

to sum up:

All containers that do not support random access iterators cannot use standard algorithms.

Such as list cannot use sort();

Corresponding algorithms will be provided internally.

  • Reverse — reverse
  • Sorting — sort (member function)

8. Sorting case

Case description: Sort the custom data type of Person. The attributes in Person are name, age, and height

Sorting rule: ascending order by age, descending order by height if the age is the same

Example:

#include <list>
#include <string>
class Person {
public:
	Person(string name, int age , int height) {
		m_Name = name;
		m_Age = age;
		m_Height = height;
	}

public:
	string m_Name;  //姓名
	int m_Age;      //年龄
	int m_Height;   //身高
};


bool ComparePerson(Person& p1, Person& p2) {

	if (p1.m_Age == p2.m_Age) {
		return p1.m_Height  > p2.m_Height;
	}
	else
	{
		return  p1.m_Age < p2.m_Age;
	}

}

void test01() {

	list<Person> L;

	Person p1("刘备", 35 , 175);
	Person p2("曹操", 45 , 180);
	Person p3("孙权", 40 , 170);
	Person p4("赵云", 25 , 190);
	Person p5("张飞", 35 , 160);
	Person p6("关羽", 35 , 200);

	L.push_back(p1);
	L.push_back(p2);
	L.push_back(p3);
	L.push_back(p4);
	L.push_back(p5);
	L.push_back(p6);

	for (list<Person>::iterator it = L.begin(); it != L.end(); it++) {
		cout << "姓名: " << it->m_Name << " 年龄: " << it->m_Age 
              << " 身高: " << it->m_Height << endl;
	}

	cout << "---------------------------------" << endl;
	L.sort(ComparePerson); //排序

	for (list<Person>::iterator it = L.begin(); it != L.end(); it++) {
		cout << "姓名: " << it->m_Name << " 年龄: " << it->m_Age 
              << " 身高: " << it->m_Height << endl;
	}
}

int main() {

	test01();

	system("pause");

	return 0;
}

to sum up:

  • For custom data types, you must specify the sorting rules, otherwise the compiler does not know how to sort

  • Advanced sorting is just another logical rule formulation on the sorting rules, which is not complicated

Guess you like

Origin blog.csdn.net/Kukeoo/article/details/114050842