VS 2010 std::list.sort函数实现的非递归merge sort

td::list.sort()采用的是mergesort算法。

merge sort的递归实现非常简单,一般为

MergeSort(1,n){

      MergeSort(1,n/2);

      MergeSort(n/2,n);

      Merge(1,n/2,n);

}

下图为用一个长度为16的序列调用MergeSort形成的归并树(节点中的m..n是序列的下标,虚三角表示省略的子树)

 

std::list.sort()虽然采用了merge sort算法,但实现上采用了非递归的方式。代码原文见最后,以下是对于代码的详细分析:

_Binlist为list的数组,数组长度为26。

while (!empty())保持了以下循环不变量:

1. _Maxbin<=25

2. 如果n属于[0,_Maxbin),且n!=24,则_Binlist[n]或者为空,或者保存了已经排好序的2^^n个元素

3. 如果n属于[0,_Maxbin),且n==24,则_Binlist[n]或者为空,或者保存了已经排好序的>=2^^n个元素

4. 如果n>=_Maxbin,_Binlist[n]为空

因此,执行完while后,后续的操作把[0,_Maxbin)范围的list全部归并起来,形成了最终的排序序列。

 

这里有趣的是元素的归并过程。

从逻辑上,可以认为_Binlist[n]为空,则_Binlist[n]取值为1,否则取值为0。因此_Binlist形成了一个二进制"0"和"1"的序列,即_Binlist逻辑上形成了一个整数。每次while循环处理一个新的元素,会导致_Binlist的list依次从低向高归并,归并的结果相当于向_Binlist整数加1;同时,_Binlist[n]取值为1或0的含义保持不变。

通过跟踪可知,std::list.sort()的归并树与递归调用完全相同。

 

_Binlist数组形成的逻辑整数

 

算法原文:

void sort()

                {       // order sequence, using operator<

                if (2 <= this->_Mysize)

                        {       // worth sorting, do it

                        const size_t _MAXBINS = 25;

                        _Myt _Templist(this->_Alval), _Binlist[_MAXBINS + 1];

                        size_t _Maxbin = 0;

                       

                        while (!empty())

                                {      

                                        // assert _Templist.size() == 0

                                        // sort another element, using bins

                                        // 每次循环处理一个元素

                                _Templist._Splice_same(_Templist.begin(), *this, begin(),

                                        ++begin(), 1);

 

                                size_t _Bin;

                                for (_Bin = 0; _Bin < _Maxbin && !_Binlist[_Bin].empty();

                                        ++_Bin)

                                        {       // merge into ever larger bins

                                        _Binlist[_Bin].merge(_Templist);

                                        _Binlist[_Bin].swap(_Templist);

                                        }

 

                                if (_Bin == _MAXBINS)

                                        _Binlist[_Bin - 1].merge(_Templist);

                                else

                                        {       // spill to new bin, while they last

                                                // assert _Binlist[_Bin].empty()

                                        _Binlist[_Bin].swap(_Templist);

                                        if (_Bin == _Maxbin)

                                                ++_Maxbin;

                                        }

                                }

 

                        // 从前到后合并_Bin数组,最后插入到self

                        for (size_t _Bin = 1; _Bin < _Maxbin; ++_Bin)

                                _Binlist[_Bin].merge(_Binlist[_Bin - 1]);      // merge up

                        splice(begin(), _Binlist[_Maxbin - 1]); // result in last bin

                        }

                }

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dim ws As Worksheet Dim lastRow As Long Set ws = ThisWorkbook.Worksheets("Sheet1") '清除格式和删除行列 ws.Cells.ClearFormats ws.Range("1:2").Delete Shift:=xlUp ws.Range("A:A,B:B,C:C,F:F,G:G,I:I,J:J,K:K,M:M,P:P,Q:Q,S:S,T:T").Delete Shift:=xlToLeft '添加新列 ws.Range("H1").Value = "回收时间" ws.Range("K1").Value = "回收人" ws.Range("L1").Value = "复核人" ws.Columns("E:E").Copy Destination:=ws.Columns("I:I") ws.Columns("F:F").Copy Destination:=ws.Columns("J:J") '筛选数据 ws.Range("A:D").AutoFilter ws.Range("A:D").AutoFilter Field:=1, Criteria1:="<>tt", VisibleDropDown:=False ws.Range("A:D").AutoFilter Field:=2, Criteria1:="<>996999", VisibleDropDown:=False ws.Range("A:D").AutoFilter Field:=3, Criteria1:="<>996999", VisibleDropDown:=False ws.Range("A:D").AutoFilter Field:=4, Criteria1:="<>*贴", Operator:=xlAnd, Criteria2:="<>*片", VisibleDropDown:=False '排序数据 With ws.Sort .SortFields.Clear .SortFields.Add2 Key:=ws.Range("A2:A500"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal .SetRange ws.Range("A1:L500") .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With With ActiveSheet .Columns.AutoFit .Rows.AutoFit .Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove .Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove .Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove End With '合并单元格 With ws.Range("A1:L1") .Merge .Value = "yyy" End With '调整列宽 ws.Columns("B:B").ColumnWidth = 7.5 ws.Columns("E:E,I:I").ColumnWidth = 3.08 End Sub 改进
最新发布
05-22

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值