STL容器与算法(四)C++ List知识点

C++ List知识点

List 是标准类库中的一个类,可以简单视之为双向链表,以线性列的方式管理物件集合。list 的特色是在集合的任何位置增加或删除元素都很快,但是不支持随机存取。双向链表的每个元素中都有一个指针指向后一个元素,也有一个指针指向前一个元素。

如图所示:
在这里插入图片描述

List与vector的区别

vector随机访问快,即下标运算;同时vector可以在尾部添加,不申请空间的情况下,非常快;缺点:不支持快速插入和删除,操作比较慢。List的内存空间是不连续的,是通过指针进行访问的,因此他的随机存取非常麻烦,没有效率,因此没有提供[ ]操做符的重载。但是它在集合的任意位置增加或删除元素都很快。


在这里插入图片描述


头文件

#include<iostream>
#include<list>
#include<algorithm>
using namespace std;

定义

list<结构体>ls;
list< int>ls;
list< sting>ls;
list< char>ls;

struct Node{
	int a;
	char c;
};
void ListDefine()
{	
	list<int> ls1;
	list<Node> ls ;
	list<char>ls2;
}

构造函数

list();
list(size_type_Count); 多个元素,均为0
list(size_type_Count, const Type&_Val); 多个指定的值
list(const_list&_Right); 用一个list初始化当前的list
list(Inputlterator _First, Inputlterator _Last ); 另一个对象中间的一段

下列用结构体构造:

struct Node{
	int a;
	char c;
};

void fun(Node& d)
{
	cout << d.a << " "  << d.c << "\n";
 } 
 void  ListConstructor()
 {
	list<Node> ls(3) ;//三个元素均为0 
	
	Node a1 = { 12 ,'a'};
	list<Node> ls1(3, a1); //三个a1, 
	
	list<Node> ls2(ls1); // 用ls1初始化ls2 
	
	list<Node> ls3( ls1.begin(),ls1.end()); //同上 
	
	for_each(ls.begin(),ls.end(),fun);
	cout << endl;
	for_each(ls1.begin(),ls1.end(),fun);
	cout << endl;
	for_each(ls2.begin(),ls2.end(),fun);
	cout << endl;
	for_each(ls3.begin(),ls3.end(),fun);
	cout << endl; 
	
	list <Node>::iterator ite = ls1.begin();
	ite++; //不能直接ite+2,会造成位置的偏移 
	list<Node> ls4(ite,ls1.end()); //取ls1中间第2到最后个初始化为ls4 
	
	for_each(ls4.begin(),ls4.end(),fun);
	}

输出结果:

在这里插入图片描述


属性

1.容量

链表不同于string,vector,不需要提前提供一定大小的空间,因其结构是链式的,可以自由的进行添加和删除。因此不存在容量的概念。

2.大小

  • size()元素个数

语法:

size_type size();

  • 返回list中的元素个数

  • size()函数返回list中元素的数量。

  • resize() 改变大小

语法:

void resize( size_type num, TYPE val );

  • 改变list的大小

  • resize()函数把list的大小改变到num。被加入的多余的元素都被赋值为val

  • empty() 是否为空

语法:

bool empty();

  • 如果list是空的则返回true
  • empty()函数返回真(true)如果链表为空,否则返回假。
struct Node{
	int a;
	char c;
};

void fun(Node& d)
{
	cout << d.a << " "  << d.c << "\n";
 } 
 
void ListSize()
{
	Node a= {12, 'a'};
	list<Node> ls(3,a); 
	
	cout << ls.size() << endl;
	
	for_each(ls.begin(),ls.end(),fun);
	
	ls.resize(5);
	cout << ls.size() << endl;
	cout << ls.empty() << endl;
	
	for_each(ls.begin(),ls.end(),fun);
 } 

在这里插入图片描述


操作

1.查

  • 输出
    1.输出全部
    • 循环,迭代器
struct Node{
	int a;
	char c;
};
void ListCout() 
{
	Node a= {12, 'a'};
	list<Node> ls(3,a); 
	
	for(list<Node>::iterator ite = ls.begin();  ite != ls.end(); ite++)
	{
		cout << ite->a << " "  << ite->c  << endl;
	}
}
* for_each()

2.输出单个元素

  • 不支持下标输出[ ]
  • back()返回尾巴的元素

语法:

reference back();

  • front()返回第一个元素

语法:

reference front();

struct Node{
	int a;
	char c;
};

void ListCout() 
{
	Node a= {12, 'a'};
	list<Node> ls(3,a); 
	
	cout << ls.back().a << " " << ls.back().c <<endl;
	cout << ls.front().a << " " << ls.front().c << endl;
}

2.增

  • push_back () 尾添加

语法:

void push_back( const TYPE &val );

  • 在list的末尾添加一个元素

  • push_back()将val连接到链表的最后。

  • push_front() 头添加

语法:

void push_front( const TYPE &val );

  • 在list的头部添加一个元素
  • push_front()函数将val连接到链表的头部。
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;


struct Node{
	int a;
	char c;
	Node(int b,char d)
	{
		a = b;
		c = d;
	}	
};
void fun(Node& d)
{
	cout << d.a << " "  << d.c << "\n";
 } 
void ListAdd()
{
	Node a(12, 'a');
	list<Node> ls(3,a); 
	ls.push_front(Node (11,'b'));
	ls.push_back(Node (13,'b'));
	for_each(ls.begin(),ls.end(),fun);
 } 
 
 int main()
 {
 	ListAdd();
 	
 	system("pause");
 	return 0;
 }

在这里插入图片描述

  • insert () 中间添加

语法:

iterator insert( iterator pos, const TYPE &val );
void insert( iterator pos, size_type num, const TYPE &val );
void insert( iterator pos, input_iterator start, input_iterator end );

  • 插入一个元素到list中
  • insert()插入元素val到位置pos,或者插入num个元素val到pos之前,或者插入start到end之间的元素到pos的位置。返回值是一个迭代器,指向被插入的元素。
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;


struct Node{
	int a;
	char c;
	Node(int b,char d)
	{
		a = b;
		c = d;
	}	
};
void fun(Node& d)
{
	cout << d.a << " "  << d.c << "\n";
 } 
void ListAdd()
{
	Node a(12, 'a');
	list<Node> ls(3,a); 
	
	list<Node>::iterator ite = ls.begin();
	ite++;
	ite++;    //第三个位置
	
	ls.insert(ite,Node (15,'d'));
	ls.insert(ite,3,Node (16,'e'));//插入三个相同的结构元素
	for_each(ls.begin(),ls.end(),fun);
 } 

输出结果:
在这里插入图片描述

3.删

  • pop_back() 尾删除

语法:

void pop_back();

pop_back()函数删除链表的最后一个元素

  • pop_frond() 头删除

语法:

void push_front( const TYPE &val );

push_front()函数将val连接到链表的头部

  • earse() 删除指定元素

语法:

iterator erase( iterator pos );
iterator erase( iterator start, iterator end );

erase()函数删除以pos指示位置的元素, 或者删除start和end之间的元素。 返回值是一个迭代器,指向最后一个被删除元素的下一个元素。

void ListDel()
{
	list<Node> ls;
	
	ls.push_back(Node(1,'a'));
	ls.push_back(Node(2,'b'));
	ls.push_back(Node(3,'c'));
	ls.push_back(Node(4,'d'));
	ls.push_back(Node(5,'e'));
	ls.push_back(Node(6,'f'));
	

	list<Node>::iterator ite = ls.begin();
	ite++;
	ite++;       //指向第三个 


	ls.pop_back();  //删除最后一个  
//	或ls.erase(--ls.end()); 效果一样 
	ls.pop_front(); //删除第一个 
	ls.erase(ite);  //删除第三个 
	
	
	
	for_each(ls.begin(),ls.end(),fun);	
}

输出结果:
在这里插入图片描述

  • clear() 清空

语法:

void clear();

clear()函数删除list的所有元素

	ls.clear();
  • remove() 删除所有指定元素

语法:

void remove( const TYPE &val );

remove()函数删除链表中所有值为val的元素。

 // 创建一个链表,元素是字母表的前10个元素
    list<char> charList;
    for( int i=0; i < 10; i++ )
      charList.push_front( i + 65 );

    // 删除所有'E'的实例
    charList.remove( 'E' );

  • unique() 删除重复元素

语法:

void unique();
void unique( BinPred pr );

unique()函数删除链表中所有重复的元素。如果指定pr,则使用pr来判定是否删除。

4.改

  • 利用迭代器修改
  • =
  • assigin() 赋值

语法:

void assign( input_iterator start, input_iterator end );
void assign( size_type num, const TYPE &val );

assign()函数以迭代器start和end指示的范围为list赋值或者为list赋值num个以val为值的元素。

void ListChange()
{
	list<Node> ls;
	
	ls.push_back(Node(1,'a'));
	ls.push_back(Node(2,'b'));
	ls.push_back(Node(3,'c'));
	ls.push_back(Node(4,'d'));
	ls.push_back(Node(5,'e'));

	ls.assign(3,Node(2,'b')); //将原ls改为三个 2b 
	
	list<Node> ls1;
	ls1 = ls; 
	
	list<Node>::iterator ite = ls1.begin();
	ite++;   
	ls1.assign(ite,ls1.end());
	
	
	for_each(ls.begin(),ls.end(),fun);	
	cout << endl;
	for_each(ls1.begin(),ls1.end(),fun);
	
}

结果:
在这里插入图片描述

5.其他

  • swap() 交换

语法:

void swap( list &lst );

swap()函数交换lst和现链表中的元素。

list<Node> ls;
	
	ls.push_back(Node(1,'a'));
	ls.push_back(Node(2,'b'));
	ls.push_back(Node(3,'c'));
	ls.push_back(Node(4,'d'));
	ls.push_back(Node(5,'e'));
	
	list<Node> ls1;
	ls1.push_back(Node(123,'a'));
	
	ls1.swap(ls);
	
	for_each(ls.begin(),ls.end(),fun);
	for_each(ls1.begin(),ls1.end(),fun);

输出结果:
在这里插入图片描述

  • reverse() 颠倒元素

语法:

void reverse();

reverse()函数把list所有元素倒转

	list<Node> ls;
	
	ls.push_back(Node(1,'a'));
	ls.push_back(Node(2,'b'));
	ls.push_back(Node(3,'c'));
	ls.push_back(Node(4,'d'));
	ls.push_back(Node(5,'e'));
	
	ls.reverse();
	
	for_each(ls.begin(),ls.end(),fun);

输出结果:
在这里插入图片描述

  • sort()

语法:

void sort();
void sort( Comp compfunction );

sort()函数为链表排序,默认是升序。如果指定compfunction的话,就采用指定函数来判定两个元素的大小。
如果容器本身自带排序,那么使用的时候,就可以不用选择算法的排序

  • merge() 合并

语法:

void merge( list &lst );
void merge( list &lst, Comp compfunction );

merge()函数把自己和lst链表连接在一起,产生一个整齐排列的组合链表。如果指定compfunction,则将指定函数作为比较的依据。

  • splice() 合并

语法:

void splice( iterator pos, list &lst );
void splice( iterator pos, list &lst, iterator del );
void splice( iterator pos, list &lst, iterator start, iterator end );

splice()函数把lst连接到pos的位置。如果指定其他参数,则插入lst中del所指元素到现链表的pos上,或者用start和end指定范围。


运算符重载

Operators
语法:

v1 == v2
v1 != v2
v1 <= v2
v1 >= v2
v1 < v2
v1 > v2

若使用的是结构体的话,进行排序、合并需要重载运算符

= 赋值运算符


用到的两个算法

需要的头文件:#include < algorithm>
遍历:for_each
查找函数:

Inputlterator find( Inputlterator _First ,Inputlterator _Last,const Type& _val );
在一个容器中查找一个成员,返回这个成员的迭代器

list<int>::iterator ite = find(ls.begin(),ls.end(),3);  //查找3返回给ite
cout << ite << endl;


上面的程序如下:

#include<iostream>
#include<list>
#include<algorithm>
using namespace std;

struct Node{
	int a;
	char c;

};

void fun(Node& d)
{
	cout << d.a << " "  << d.c << "\n";
 } 
 
 
//定义 
void ListDefine()
{	
	//list<int> ls1;
	list<Node> ls(3) ;//三个元素均为0 
	for_each(ls.begin(),ls.end(),fun);

}

//构造函数
void  ListConstructor()
{
	list<Node> ls(5);
	
	Node a1 = { 12 ,'a'};
	list<Node> ls1(3, a1); //三个a1, 
	
	list<Node> ls2(ls1); // 用ls1初始化ls2 
	
	list<Node> ls3( ls1.begin(),ls1.end()); //同上 
	
	for_each(ls.begin(),ls.end(),fun);
	cout << endl;
	for_each(ls1.begin(),ls1.end(),fun);
	cout << endl;
	for_each(ls2.begin(),ls2.end(),fun);
	cout << endl;
	for_each(ls3.begin(),ls3.end(),fun);
	cout << endl; 
	
	list <Node>::iterator ite = ls1.begin();
	ite++; //不能直接ite+2,会造成位置的偏移 
	list<Node> ls4(ite,ls1.end()); //取ls1中间第2到最后个初始化为ls4 
	for_each(ls4.begin(),ls4.end(),fun);
	
	
}

//大小
void ListSize()
{
	Node a= {12, 'a'};
	list<Node> ls(3,a); 
	
	cout << ls.size() << endl;
	
	for_each(ls.begin(),ls.end(),fun);
	
	ls.resize(5);
	cout << ls.size() << endl;
	cout << ls.empty() << endl;
	
	for_each(ls.begin(),ls.end(),fun);
 } 
 
 //查
void ListCout() 
{
	Node a= {12, 'a'};
	list<Node> ls(3,a); 
	
	for(list<Node>::iterator ite = ls.begin();  ite != ls.end(); ite++)
	{
		cout << ite->a << " "  << ite->c  << endl;
	}
	
	cout << ls.back().a << " " << ls.back().c <<endl;
	cout << ls.front().a << " " << ls.front().c << endl;
}

 
int main()
{
	//ListDefine();
	//ListConstructor();
	//ListSize(); 
	//ListCout();
	//ListAdd();
	
	system("pause");
	return 0;
 } 
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;


struct Node{
	int a;
	char c;
	Node(int b,char d)
	{
		a = b;
		c = d;
	}	
};
void fun(Node& d)
{
	cout << d.a << " "  << d.c << "\n";
 } 
void ListAdd()
{
	Node a(12, 'a');
	list<Node> ls(3,a); 
//	ls.push_front(Node (11,'b'));
//	ls.push_back(Node (13,'b'));
//	for_each(ls.begin(),ls.end(),fun);
//	
//	cout << endl;
	
	list<Node>::iterator ite = ls.begin();
	ite++;
	ite++;
	
	ls.insert(ite,Node (15,'d'));
	ls.insert(ite,3,Node (16,'e'));
	for_each(ls.begin(),ls.end(),fun);
 } 
 
void ListDel()
{
	list<Node> ls;
	
	ls.push_back(Node(1,'a'));
	ls.push_back(Node(2,'b'));
	ls.push_back(Node(3,'c'));
	ls.push_back(Node(4,'d'));
	ls.push_back(Node(5,'e'));
	ls.push_back(Node(6,'f'));
	

	list<Node>::iterator ite = ls.begin();
	ite++;
	ite++;       //指向第三个 


	ls.pop_back();  //删除最后一个  
//	或ls.erase(--ls.end()); 效果一样 
	ls.pop_front(); //删除第一个 
	ls.erase(ite);  //删除第三个 
	
//	ls.clear();
	
	for_each(ls.begin(),ls.end(),fun);	
}
 
void ListChange()
{
	list<Node> ls;
	
	ls.push_back(Node(1,'a'));
	ls.push_back(Node(2,'b'));
	ls.push_back(Node(3,'c'));
	ls.push_back(Node(4,'d'));
	ls.push_back(Node(5,'e'));

	ls.assign(3,Node(2,'b')); //将原ls改为三个 2b 
	
	list<Node> ls1;
	ls1 = ls; 
	
	list<Node>::iterator ite = ls1.begin();
	ite++;   
	ls1.assign(ite,ls1.end());
	
	
	for_each(ls.begin(),ls.end(),fun);	
	cout << endl;
	for_each(ls1.begin(),ls1.end(),fun);
	
}
 
void ListDo()
{
	list<Node> ls;
	
	ls.push_back(Node(1,'a'));
	ls.push_back(Node(2,'b'));
	ls.push_back(Node(3,'c'));
	ls.push_back(Node(4,'d'));
	ls.push_back(Node(5,'e'));
	
	list<Node> ls1;
	ls1.push_back(Node(123,'a'));
	
//	ls1.swap(ls);
	
//	ls.reverse();
	
	list<Node>::iterator ite = find(ls.begin(),ls.end(),Node(3,'c'));
	cout << ite->a << " " << ite->c << endl;
	
	for_each(ls.begin(),ls.end(),fun);
//	for_each(ls1.begin(),ls1.end(),fun);	
}
 
 
 int main()
 {
 	//ListAdd();
 	//ListDel();
 	//ListChange();
 	ListDo();
 	
 	system("pause");
 	return 0;
 }
发布了17 篇原创文章 · 获赞 76 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/diviner_s/article/details/104282291
今日推荐