时间: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; }
链表类型list和foreard_list的特定容器算法