【STL】list容器使用与模拟

STL里的list容器里实现了许多接口,list也是我们最常用的容器之一,所以有必要熟练的运用这些接口

1.定义链表的几种方式

 std::list<int> first;                                // 构造一个空链表
  std::list<int> second (4,100);                       // 构造一个有四个整形结点的链表
  std::list<int> third (second.begin(),second.end());  // 使用左闭右开的迭代器区间进行构造
  std::list<int> fourth (third);                       // 调用拷贝构造

  // 还可以用数组区间进行构造
  int myints[] = {16,2,77,29};
  std::list<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );


2.和迭代器有关的几个常用接口


void Testlist()
{
	list<int> s1;
	s1.push_back(1);
	s1.push_back(2);
	s1.push_back(3);
	s1.push_back(4);
	s1.push_back(5);

	
	//Iterator部分的操作
	//1.begin & end(配合iterator使用)
	list<int>::iterator it1 = s1.begin();
	cout << "正向迭代器打印:";
	while (it1!=s1.end())
	{
		cout<< *it1 <<" ";
		++it1;
	}
	cout << endl;

	//2.rbegin & rend (配合reverse_iterator使用)
	list<int>::reverse_iterator rit1 = s1.rbegin();
	cout << "反向迭代器打印:";
	while (rit1 != s1.rend())
	{
		cout<< *rit1 << " ";
		++rit1;
	}
	cout << endl;


3.和容器容量有关的接口


	cout << s1.max_size() << endl;
	cout << s1.size() << endl;


max_size()返回的是容器的最大容量,等于内存最大容量/结点大小

size()返回容器当前结点的个数

empty()是判断容器是否为空,为空返回true,非空返回false;


4.一些作用容器的算法


	//4.void resize (size_type n, value_type val = value_type());
	cout << "resize:" << endl;
	print(s1);
	s1.resize(7,5);//改变list的容量,并把增加的结点插入5
	print(s1);
	s1.resize(10); //改变list容量,若没指定插入的值,默认为0
	print(s1);
	s1.resize(4);//改变list容量,若是所需容量,则删除后面的结点
	print(s1);



	//5.void remove (const value_type& val);
	cout << "remove:" << endl;
	s1.resize(10, 1);
	print(s1);
	s1.remove(1);  //删除list里所有的指定的元素
	print(s1);


/*6.void splice (iterator position, list& x);
		void splice(iterator position, list& x, iterator i);
		void splice(iterator position, list& x, iterator first, iterator last);*/
	cout << "splice:" <<endl ;
	cout << "s2.splice(s2.begin(), s1);" << endl;
	list<int> s2;
	print(s1);         //s :2 3 4
	print(s2);        //s2:
	s2.splice(s2.begin(), s1); //把s1链表里的值插入到时s2链表里的begin()前面,并删除s1里的数据
	print(s1);         //s :
	print(s2);		  //s2:2 3 4

	cout <<"s1.splice(it1, s2, s2.begin());"<< endl;
	s1.push_back(10);
	s1.push_back(20);
	s1.push_back(30);
	it1 = s1.begin();
	++it1;    //it1 指向 20
	print(s1);                      //s :10 20 30
	print(s2);                     //s2: 2  3  4 
	s1.splice(it1, s2, s2.begin()); //在s1链表里元素20的前面插入s2的begin()元素,并删除s2里的begin元素
	print(s1);					   //s  :10 2 20 30
	print(s2);                     //s2 : 3 4
	cout << "s2.splice(s2.begin(), s1, it1,s1.end());" << endl;
	list<int>::iterator it2 = s2.begin();
	++it2;
	print(s1);
	print(s2);
	s2.splice(s2.begin(), s1, it1,s1.end()); //把s1链表里的20-30这个区间里的值插入到s2链表begin前面
	print(s1);       
	print(s2);		  



//7.reverse
	cout << "reverse" << endl;
	print(s2);
	s2.reverse();  //将链表里的元素逆序打印一遍
	print(s2);



	//8.sort
	cout << "sort" << endl;
	s2.sort();    //将链表的元素按照升序排序
	print(s2);

	//9.merge 合并链表
	cout << "merge" << endl;
	s1.sort();
	s2.sort();
	print(s1);
	print(s2);
	s1.merge(s2);  //将两个有序链表合并起来,并且合并后也有序,另一个链表被删除
	print(s1);
	print(s2);

	//10.unique
	cout << "unique" << endl;
	s1.push_back(10);
	print(s1);
	s1.sort();  
	s1.unique();  //删除有序链表里重复的值
	print(s1);

注意:merge和unique都是对有序链表进行操作





5.对容器进行增删改的接口


//12.assign
	cout << "assign" << endl;
	print(s1);
	int a[] = { 1, 2, 3, 4, 5 };
	s1.assign(a+1 , a + 3);  //重新分配链表里的内容,并重新修改其大小,注意参数是左闭右开区间。
	print(s1);



//13.void resize (size_type n, value_type val = value_type());调整容器的大小,使其包含n个元素。
	for (int i = 1; i<10; ++i) 
		s1.push_back(i);
	print(s1);
	s1.resize(5);
	print(s1);
	s1.resize(8, 100);
	print(s1);
	s1.resize(12);
	print(s1);


//emplace操作是C++11新特性

新引入的的三个成员emlace_front、empace 和 emplace_back,这些操作构造而不是拷贝元素到容器中,这些操作分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部。

例子 

假定d是一个Date类型的容器。 

//使用三个参数的Date构造函数,在容器管理的内存空间中构造新元素。 
d.emplace_back(“2016”,”05”,”26”);

//错误,push_back没有这种用法 
d.push_back(“2016”,”05”,”26”);

//push_back()创建一个临时对象,然后将临时对象拷贝到容器中 
d.push_back(Date(“2016”,”05”,”26”));

通过例子发现,使用C++11新特性emplace向容器中添加新元素,在容器管理的内存空间中构造新元素,与insert相比,省去了构造临时对象,减少了内存开销。

两者的区别 
当调用insert时,我们将元素类型的对象传递给insert,元素的对象被拷贝到容器中,而当我们使用emplace时,我们将参数传递元素类型的构造函函数,emplace使用这些参数在容器管理的内存空间中直接构造元素。

注意:emplace函数在容器中直接构造元素,传递给emplace函数的参数必须与元素类型的构造函数相匹配。


//insert()

single element (1)
iterator insert (iterator position, const value_type& val);
fill (2)
    void insert (iterator position, size_type n, const value_type& val);
range (3)
template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);

position代表迭代器指针

val代表要插入的值

n代表插入几个val

first和last代表左闭右开的迭代器区间,可以把其他容器的值插入本容器

        list<int> mylist;
	list<int>::iterator it = mylist.begin();
	vector<int> myvector(5, 10);
	mylist.insert(it, myvector.begin(), myvector.end());
	print(mylist);  // 正向迭代器打印:10 10 10 10 10

其他一些比较熟悉的增删改的接口,就不演示了。

模拟stl里的list代码:github







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值