- template <class T, class Alloc>
- void list<T, Alloc>::sort() {
- if (node->next == node || link_type(node->next)->next == node) return;
- list<T, Alloc> carry;
- list<T, 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);
- 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]);
- swap(counter[fill-1]);
- }
抛开算法复杂度不说,这个算法很好地复用了List类中定义的其它成员函数。
carry每次循环开始从this中splice头部的node,保证了参与merge的List始终是有序的。counter[]作为排序中介List,通过与carry中的数据merge达到排序的目的,swap的恰当使用保证了将carry中数据转至counter[],也保证了carry在循环开始可以轻装上阵,为splice做好准备。
算法思想别具一格,可谓STL算法中的上佳之作。
自己改了一下代码,以便可以显示排序过程:
- template <typename T>
- void sort_list(list<T> &lst)
- {
- if(lst.size()<2)
- return;
- list<T> carry;
- list<T> counter[64];
- int fill = 0;
- typename list<T>::iterator it;
- while (!lst.empty()) {
- carry.splice(carry.begin(), lst, lst.begin());
- cout<<"carry: ";
- it=carry.begin();
- while(it!=carry.end())
- cout<<*it++<<" ";
- cout<<endl;
- int i = 0;
- while(i < fill && !counter[i].empty()) {
- counter[i].merge(carry);
- carry.swap(counter[i++]);
- }
- carry.swap(counter[i]);
- for(int i=0;i<fill+1;i++)
- {
- it=counter[i].begin();
- cout<<"counter"<<i<<": ";
- while(it!=counter[i].end())
- cout<<*it++<<" ";
- cout<<endl;
- }
- if (i == fill) ++fill;
- cout<<endl;
- }
- for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]);
- it=counter[fill-1].begin();
- cout<<"counter"<<fill-1<<": ";
- while(it!=counter[fill-1].end())
- cout<<*it++<<" ";
- cout<<endl;
- lst.swap(counter[fill-1]);
- }
- int main()
- {
- int arr[]={10,88,45,87,65,96,84,8,86,53,67,5,48,74,4,35,71,25,32};
- list<int> lst(arr,arr+sizeof(arr)/sizeof(int));
- list<int>::iterator it=lst.begin();
- while(it!=lst.end())
- cout<<*it++<<" ";
- cout<<endl;
- sort_list(lst);
- return 0;
- }