C++ STL链表排序问题

这是一段从STL中摘录下来的代码,它声称对链表做了排序的工作:

  template<typename _Tp, typename _Alloc>
    void
    list<_Tp,_Alloc>::
    sort()
    {
    
    
      // Do nothing if the list has length 0 or 1.
      if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
          && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
      {
    
    
        list __carry;
        list __tmp[64];
        list * __fill = &__tmp[0];
        list * __counter;

        do
          {
    
    
            __carry.splice(__carry.begin(), *this, begin());

            for(__counter = &__tmp[0];
                (__counter != __fill) && !__counter->empty();
                ++__counter)
              {
    
    
                __counter->merge(__carry);
                __carry.swap(*__counter);
              }
            __carry.swap(*__counter);
            if (__counter == __fill)
              ++__fill;
          }
        while ( !empty() );

        for (__counter =  &__tmp[1]; __counter != __fill; ++__counter)
          __counter->merge( *(__counter-1) );
        swap( *(__fill-1) );
      }
    }

这里__tmp[64]这个声明非常抢眼,要了解排序是怎么做的,就从这个地方找突破口。

对list稍作改造,增加一个flag数据。并把counter和fill换个名字,改做叫
order和high。merge()也改装成+= 运算。于是得到这样一个程序:

#include <iostream>
#include <list>
using namespace std;

class LIST:public list<int> {
    
    
public:
        LIST():flag(0){
    
    }
        int flag;

        LIST &operator+=(LIST &l) {
    
    
                merge(l);
                return *this;
        }
        void LIST:: sort();

};


void LIST:: sort()
{
    
    
    // Do nothing if the LIST has length 0 or 1.
    if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
        && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
        {
    
    
            LIST __carry;
            LIST __tmp[64];
            LIST * __high = &__tmp[0];
            LIST * __order;

            do
            {
    
    
                __carry.splice(__carry.begin(), *this, begin());
                __carry.flag=1;

                cout<<"tmp:";
                for(int i=64-1; i>=0; i--) cout<<__tmp[i].flag;
                cout<<"  carry:"<<__carry.flag<<"\n";

                for(__order = &__tmp[0];
                    (__order != __high) && !__order->empty();
                    ++__order)
                    {
    
    
                         *__order+= __carry;
                         __carry.swap(*__order);
                         __order->flag=0;
                         __carry.flag=1;
                    }
                    __carry.swap(*__order);
                    __order->flag=1;
                    __carry.flag=0;

                    if (__order == __high)
                             ++__high;
            }
            while ( !empty() );

            for (__order =  &__tmp[1]; __order != __high; ++__order)
                 *__order +=  *(__order-1);
            swap( *(__high-1) );
       }
}

void print(LIST &l)
{
    
    
        LIST::iterator it;
        for(it=l.begin(); it!=l.end(); it++) {
    
    
                cout << *it << "  ";
        }
        cout <<"\n";
}

int main()
{
    
    
        int arr[] = {
    
     9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
        list<int> li(&arr[0], &arr[10]);
        LIST l;
        l.swap(li);
        print(l);
        l.sort();
        print(l);
}

观察一下运行结果:

9  8  7  6  5  4  3  2  1  0
tmp:0000000000000000000000000000000000000000000000000000000000000000  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000000001  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000000010  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000000011  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000000100  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000000101  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000000110  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000000111  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000001000  carry:1
tmp:0000000000000000000000000000000000000000000000000000000000001001  carry:1
0  1  2  3  4  5  6  7  8  9

原来这是一个64位2进制数和一个进位相加的流程!是的,list的merge()做了2路归并的排序工作。把它放到一个64位2进制数和一个进位相加的流程中,于是得到了链表排序算法。

猜你喜欢

转载自blog.csdn.net/aaasssdddd96/article/details/108290017