这是一段从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进制数和一个进位相加的流程中,于是得到了链表排序算法。