C++ STL list 成员函数 sort算法分析

来源:互联网 发布:怎么推淘宝的宝贝 编辑:程序博客网 时间:2024/06/03 19:43

最近在读《STL源码剖析》,颇有收获。当看到list结构的排序方法sort时,发现侯捷先生点到为止,说采用的是快速排序,也没有继续说明。我心存疑虑,怎么看这个代码都不像快排。

 

template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
{
  // Do nothing if the list has length 0 or 1.
  if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
    list<_Tp, _Alloc> __carry;
    list<_Tp, _Alloc> __counter[64];
    int __fill = 0;
    while (!empty()) {
      __carry.splice(__carry.begin(), *this, begin());
      int __i = 0;
      while(__i < __fill && !__counter[__i].empty()) {
        __counter[__i].merge(__carry, __comp);
        __carry.swap(__counter[__i++]);
      }
      __carry.swap(__counter[__i]);        
      if (__i == __fill) ++__fill;
    }

    for (int __i = 1; __i < __fill; ++__i)
      __counter[__i].merge(__counter[__i-1], __comp);
    swap(__counter[__fill-1]);
  }
}

上网搜了一下,

http://blog.csdn.net/longhuihu/archive/2011/01/22/6158227.aspx

这位哥们儿仔细分析了一下,说是归并排序,我看了看,似乎是这样,但还是理解的不是很透彻。

后面想了一办法,由于机器上暂时只有VS2010的环境,于是断点跟踪了一下微软的实现,才总算弄明白。

template<class _Pr3>
  void sort(_Pr3 _Pred)
  { // order sequence, using _Pred
  if (2 <= this->_Mysize)
   { // worth sorting, do it
   const size_t _MAXBINS = 25;
   _Myt _Templist(this->_Alval), _Binlist[_MAXBINS + 1];
   size_t _Maxbin = 0;

   while (!empty())
    { // sort another element, using bins
    _Templist._Splice_same(_Templist.begin(), *this, begin(),
     ++begin(), 1);

    size_t _Bin;
    for (_Bin = 0; _Bin < _Maxbin && !_Binlist[_Bin].empty();
     ++_Bin)
     { // merge into ever larger bins
     _Binlist[_Bin].merge(_Templist, _Pred);
     _Binlist[_Bin].swap(_Templist);
     }

    if (_Bin == _MAXBINS)
     _Binlist[_Bin - 1].merge(_Templist, _Pred);
    else
     { // spill to new bin, while they last
     _Binlist[_Bin].swap(_Templist);
     if (_Bin == _Maxbin)
      ++_Maxbin;
     }
    }

   for (size_t _Bin = 1; _Bin < _Maxbin; ++_Bin)
    _Binlist[_Bin].merge(_Binlist[_Bin - 1],
     _Pred); // merge up
   splice(begin(), _Binlist[_Maxbin - 1]); // result in last bin
   }
  }

 

总结:看算法晕忽忽的时候,尝试写段客户程序调用,并打断点跟踪程序,容易理清思路。

本文的算法是一个巧妙的归并:

比如一个7元素的排序,在内存中各个list的状态呈现如下的状态:

1,

1,1

1,1,1,1

每次归并一个元素,要么放在当前list(当前为空的情况),要么归并后放在下一层list.

原创粉丝点击