STL源码剖析——list容器的排序算法sort()

本文详细介绍了STL中list容器的排序算法sort的实现原理,由于list的双向迭代器特性,不能直接使用STL内置的sort,而是需要自定义排序算法。该算法类似归并排序,通过创建辅助链表counter和carry,进行数据的转移和合并,最终实现list的排序。文章通过源码分析和执行流程图解,帮助读者理解排序过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

    由于STL本身的排序算法sort接受的输入迭代器是随机访问迭代器,但是双向list链表容器的访问方式是双向迭代器,因此,不能使用STL本身的排序算法sort,必须自己定义属于自己访问的排序算法。我们从源码的剖析中,可以看到该排序算法思想类似于归并排序。

list容器之排序算法sort

    在该排序算法的实现过程中,定义了一个类似于搬运作用的链表carry和具有中转站作用的链表counter,这里首先对counter[i]里面存储数据的规则进行分析;counter[i]里面最多存储数据个数为,若存储数据超过该数字,则向相邻高位进位,即把counter[i]链表里的内容都合并到counter[i+1]链表。carry负责取出原始链表的头一个数据节点和交换数据中转站作用;源码中的fill表示当前可处理数据的个数为。下面给出sort的源码分析:

//按升序进行排序,list链表的迭代器访问时双向迭代器
//因为STL的排序算法函数sort()是接受随机访问迭代器,在这里并不适合
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::sort()
{
  // 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;//carry链表起到搬运的作用
	//counter链表是中间存储作用
	/*
	*其中对于counter[i]里面最多的存储数据为2^(i+1)个节点
	*若超出则向高位进位即counter[i+1]
	*/
    list<_Tp, _Alloc> __counter[64];
    int __fill = 0;
    while (!empty()) 
	{//若不是空链表
		//第一步:
      __carry.splice(__carry.begin(), *this, begin());//把当前链表的第一个节点放在carry链表头
      int __i = 0;
      while(__i < __fill && !__counter[__i].empty()) 
	  {
        //第二步:
		  __counter[__i].merge(__carry);//把链表carry合并到counter[i]
        //第三步:
		  __carry.swap(__counter[__i++]);//交换链表carry和counter[i]内容
      }
      //第四步:
	  __carry.swap(__counter[__i]);//交换链表carry和counter[i]内容         
      //第五步:
	  if (__i == __fill) ++__fill;
    } 

    for (int __i = 1; __i < __fill; ++__i)
      //第六步:
		__counter[__i].merge(__counter[__i-1]);//把低位不满足进位的剩余数据全部有序的合并到上一位
    //第七步:
	swap(__counter[__fill-1]);//最后把已排序好的链表内容交换到当前链表
  }
}

    从源码中,我们可以看到,第一个while循环执行的条件是当前链表必须非空,该算法的核心就是while里面的处理,嵌套while(即第二个while)执行的条件是i小于fill</

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值