STL list实现(二)

 

STL list实现(2)

 

在之前的一篇文章里,讲述了list的声明和部分函数的实现。(请参考stl list实现一)在这一篇文章里 ,将向大家介绍一些常用函数的实现。

 

一.  

List的删除:list支持删除所有指定的值。 记住,listremove的参数为VALUE, 不支持参数为iterator.

Erase的参数为迭代器。

为什么remove()erase()的语义区别这么大呢?我觉得可能与单词的语义有关,removeerase都是删除。前者偏重于移动,删除。后者偏重于删除,清除。当然,这只是我个人的想法。

template <class T /*, class Alloc*/>

void list<T /*, Alloc*/>::remove(const T& value) {

    iterator first = begin(); // 取得头节点

    iterator last = end();  // 末尾节点

    while (first != last) { // 遍历节点

   iterator next = first;

   ++next;

   if (*first == value)

erase(first); //  如果内容匹配,则删除这个节点。

   first = next;   //

    }

}

 

在这个函数里,临时变量next的作用是保存和恢复first的值。因为再调用erase(first)后,first是会失效的。

 

: listUnique方法

 

template <class T >

void list<T>::unique()

{

    iterator first = begin();  // 取得头节点

    iterator last = end();      // 取得end节点

    if (first == last) return;  //list为空时,返回

iterator next = first;  // 临时变量next

 

while (++next != last) {  // 遍历所有节点

   if (*first == *next)        //  如果相邻两节点相等

       erase(next);          // 则删除两者中的后者,保留前者

   else                       // 如果不相等,继续

       first = next;

 

   next = first;   //使nextfirst保持相等

    }

}

 

由这个实现可以知道,unique只是删除连续相等的元素。所以要使容器的元素不重复,你首先需要调用sort排序。为什么呢? Unique只对已经排好序的容器有效。这一点你必须要注意。用一位哥们的话说,这很干。

带有predicate policyunique就不再这里说了。道理是一样的。

给个函数的测试用例吧:

 

#include <iostream>

#include <cmath>

#include <list>

using namespace std;

 

// a binary predicate implemented as a function:

bool same_integral_part (double first, double second)

{ return ( int(first)==int(second) ); }

 

// a binary predicate implemented as a class:

class is_near

{

public:

  bool operator() (double first, double second)

  { return (fabs(first-second)<5.0); }

};

 

int main ()

{

  double mydoubles[]={ 12.15,  2.72, 73.0,  12.77,  3.14,                  12.77, 73.35, 72.25, 15.3,  72.25 };

  list<double> mylist (mydoubles,mydoubles+10);

  mylist.sort();    //  2.72,  3.14, 12.15,12.77, 12.77,

                       // 15.3,  72.25, 72.25, 73.0,  73.35

  mylist.unique();     //  2.72,  3.14, 12.15, 12.77

                          // 15.3,  72.25, 73.0,  73.35

  mylist.unique (same_integral_part); //2.72, 3.14, 12.15 15.372.25, 73.0

  mylist.unique (is_near());   //  2.72, 12.15, 72.25

 

  cout << "mylist contains:";

 

  for (list<double>::iterator it=mylist.begin(); it!=mylist.end(); ++it )

     cout << " " << *it;

  cout << endl;

 

  return 0;

}

 

 

三: listmerge

将两个有序的list合并到一起。其中后一个list的元素会被清空。

注意,如果将无序的list合并,请使用slice函数

template <class T >

void list<T>::merge(list<T>& x)

 {

    iterator first1 = begin(); // 取得第一个list的头

iterator last1 = end();  // 取得第一个list的尾

 iterator first2 = x.begin();  //取得第二个list的头

iterator last2 = x.end();  // 取得第二个list的尾

// 该算法思想是:用一个迭代器引用x的元素,另一个迭代器引用和维护另一个list的插入position。如果x的元素比插入位置的元 素小,该元素会被从x中删除并插入到另一个list里。否则 当前插 入点会增加。当任何一个list到达末尾时,以上过程就完成。如果此时x尚未到达末尾,那么则把x剩下的所有元素插入到另一个列表的末尾。

 

    while (first1 != last1 && first2 != last2)

    {

   if (*first2 < *first1)

{ 

         iterator next = first2;

         transfer(first1, first2, ++next);

         first2 = next;

     } else

         ++first1;

} // end of while

    //如果x还未到达末尾

    if (first2 != last2) transfer(last1, first2, last2);

 

length += x.length;

 

    x.length= 0;

}

 

Listmergec语言里也是一个很常见的算法。C++merge算法和cmerge思想是一致的。

Merge的用法示例:

 

// list::merge
#include <iostream>
#include <list>
using namespace std;
 
// this compares equal two doubles if
//  their interger equivalents are equal
bool mycomparison (double first, double second)
{ return ( int(first)<int(second) ); }
int main ()
{
  list<double> first, second;
  first.push_back (3.1);
  first.push_back (2.2);
  first.push_back (2.9);
  second.push_back (3.7);
  second.push_back (7.1);
  second.push_back (1.4);
  first.sort();
  second.sort();
  first.merge(second);
  second.push_back (2.1);
  first.merge(second,mycomparison);
  cout << "first contains:";
  for (list<double>::iterator it=first.begin(); it!=first.end(); ++it)
    cout << " " << *it;
  cout << endl;
  return 0;
}

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值