首页 > 代码库 > 链表类型list和foreard_list的特定容器算法

链表类型list和foreard_list的特定容器算法

时间:2014.06.07

地点:基地

---------------------------------------------------------------------------

一、简述

  由于list和forward_list分别提供了双向迭代器和前向迭代器,因此,凡要求随机访问迭代器的通用泛型算法是不能作用于链表的。另外,也正由于链表自身的性质,通用的算法作用于链表时或许又代价太高,因为它们往往使用交换输入序列中的元素,而链表无需交换元素,只需简单的改变元素间的链接即可,于是链表版本的算法性能比通用版本的要好。

---------------------------------------------------------------------------

二、详情

  对于list和forward_list,优先使用成员函数版本的算法,而不是使用通用算法。

这些成员函数版本的算法又如下:

lst.merge(lst2);                //使用 < 运算符将list2的元素合并入lst,lst和lst2都必须是有序,而且元素将从lst2中删除,在合并之后,lst2会变为空。即相当于元素移动操作,注意这里是合并,不是拼接,后面会说道链表拼接的概念

lst.merge(lst2,comp);      //使用给定比较操作,将lst2中的元素移动到lst中


lst.remove(val);                //调用erase删除与给定值相等的所有元素

lst.remove_if(pred);          //调用erase删除使得一元谓词为真的所有元素


lst.reverse()                     //反转lst中元素的顺序


lst.sort();                           //使用 < 运算符或给定操作排序

lst.sort(comp)


lst.unique()                   //调用erase删除同一值连续冗余副本,这里使用 == 操作符

lst.unique(pred);          //调用erase删除使得二元谓词为真的连续冗余副本

以上5大特定容器算法对于list和forward_list均适用。


再来看一个splice算法,splice即接合和拼接的意思,与merge不一样的是splice是将两个链表简单地拼接在一起,而不实现元素融合merge:

lst.splice(p,lst2);                       //p是lst中元素的迭代器,或者是flst首前位置的迭代器,将lst2的所有元素移动到lst中p之前的位置,

flst.splice_after(p,lst2);            //或者是flst中p之后的位置。且lst2的类型必须与lst或flst相同,且不能是链表自己


lst.splice(p,lst2,p2);                  //p2是lst2中元素的迭代器,将p2指向的元素移动到lst中,或将p2之后的元素移动到flst中,lst2在这里可以

flst.splice_after(p,lst2,p2)         //是与lst或flst相同的链表


lst.splice(p,lst2,b,e);                 //b 和 e是一对迭代器,能表示lst2的合法范围,将给定范围内的元素移动到lst或flst中,lst2可以与lst或

flst.splice_afte(p,lst2,b,e)         //flst是相同的链表,只是p不能指向给定范围中的元素

---------------------------------------------------------------------------

三、链表特定容器算法特定表现

  与通用的容器算法不一样,链表特定的容器算法它会改变容器,比如remove操作它会很实在地移动指定元素,元素被移动后,在本链表中就不再存在,又比如unique操作会很实在的删除冗余的元素。merge和splice也是一样,我们知道通用版的merge是将两个序列合并后写入第三个目的迭代器,输入序列并不改变,而链表版的merge函数会从一个链表中将元素移动到指定链表中,注意是移动,不是copy。

---------------------------------------------------------------------------

四、练习题

  删除重复单词

#include<iostream>
#include<list>
#include<string>
using namespace std;
void ElimDups(list<string>& words_list)
{
	words_list.sort();
	words_list.unique();
}
int main()
{
	list<string> words_list;
	string word;
	cout << "Input words: " << endl;
	while (cin>>word)
	{
		words_list.push_front(word);
	}
	ElimDups(words_list);
	for (auto word : words_list)
		cout << word << " ";
	cout << endl;
}