STL中list的sort 疑惑

budweiser 2009-10-01 09:16:31
STL中list的sort源码为:

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]);
}


侯捷在书中说这是快排,但本人弄不清楚该算法,而且我总觉得 fill 有可能一直加到大于64.
望了解的人解释下。
...全文
213 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
眼睛猥琐男 2009-10-01
  • 打赏
  • 举报
回复
帮顶哦
wendll 2009-10-01
  • 打赏
  • 举报
回复
2楼的解释不错
counter[i]中存放的是含有pow(2,i+1)-1个数,pow(2,i+1)表示2的(i+1)次方
即counter[0]中最多存长度为1的list
counter[1]中最多存长度为3的list
依次类推

当我们从源list中取一个节点放入cout数组中时,就是从counter[0]放起,如果counter[0]为空则放入counter[0],如果不为空,则放入counter[0],由于counter[0]中最多能放入1个节点的list,可以知道,再放入1个list节点counter[0]就满了,将把counter[0]的元素移动到counter[1],如果counter[1]为空,则直接复制到counter[1]中,否则counter[1]中有两个list节点(counter[1]中有节点就肯定会是2个,因为counter[1]相当如是从counter[0]进位来的),加上刚从counter[0]进位的2个list节点,counter[1]中将会有4个节点,超过其容量3个节点,将往counter[2]进位,如此类推。。。。
while(i < fill && !counter[i].empty()) 中的逻辑判断用的非常好,二进制的妙用,这个程序应该算是淋漓尽致了
hyram 2009-10-01
  • 打赏
  • 举报
回复
自底向上归并排序
第一个元素放入counter[0]
第二个元素发现counter[0]不为空,和他合并,放入counter[1];counter[0]置空
第三个元素放入counter[0]
第四个元素发现counter[0]不为空,和他合并,又发现counter[1]不为空,在和他合并,放入counter[2],counter[0]和counter[1]置空。
就是说每次小的用完了,才会和最大的合并,放到新的里。每次合并大小乘2,就是说没占用一个新的,范围就扩大一倍,64个数组能存到2的63次方,所以fill是不大可能加到这么大的。

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧