【Delphi】对 QuickSort 函数的理解分类

【Delphi】对 QuickSort 函数的理解分类: 【Delphi XE】组件学习笔记 2012-01-01 16:14 233人阅读 评论(0) 收藏 举报在 Delphi 的 Classes 单元定义了 TList 类,TList 有一个 Sort 方法,用来对 TList 里面的指针数组进行排序,这个方法调用了 QuickSort 函数,这个函数不好理解,我看了很久才看明白。记录下来,以免将来忘记了。[delphi] view plaincopy { 对指针进行排序,Compare 为排序函数 } procedure TList.Sort(Compare: TListSortCompare); begin if (FList <> nil) and (Count > 1) then { 调用 Compare 进行排序 } QuickSort(FList, 0, Count - 1, function(Item1, Item2: Pointer): Integer begin Result := Compare(Item1, Item2); end); end; TListSortCompare = function (Item1, Item2: Pointer): Integer; { 快速排序过程 } { SortList:指针数组 L:排序范围的最左边(头) R:排序范围的最右边(尾) SCompare:比较两个指针所指内容大小的函数 } procedure QuickSort(SortList: PPointerList; L, R: Integer; SCompare: TListSortCompareFunc); var I, J: Integer; { 用来移动并查找元素的位置值 } P, T: Pointer; { 存放中间元素和临时元素 } begin repeat { 设定刚开始查找时的起始位置 I 和结束位置 J } I := L; { 最小 Index } J := R; { 最大 Index } { 获取范围正中间的元素 P 的值 } { (L + R) shr 1 相当于 (L + R) div 2 } P := SortList^[(L + R) shr 1]; repeat { 从 I 开始向后找比 P 大(>=)的元素 } while SCompare(SortList^[I], P) < 0 do Inc(I); { 从 J 开始向前找比 P 小(<=)的元素 } while SCompare(SortList^[J], P) > 0 do Dec(J); { 判断 I 和 J 是否碰过头(I > J 就表示已经碰过头了) } { 刚碰头不算,碰头后继续走一步才算碰过头 } if I <= J then begin { 如果还没有碰头,则交换 I 和 J 的元素值,小的排前面,大的排后面 } { 如果 I 和 J 刚碰头并且都指向同一个元素(I = J),则没必要自己和自己交换 } if I <> J then begin T := SortList^[I]; SortList^[I] := SortList^[J]; SortList^[J] := T; end; { I 和 J 各自向各自方向走一步,继续比较下一个元素 } Inc(I); Dec(J); end; { 如果已经碰过头,则退出此轮循环 } { 此时应该是 I := J + 1,即:I 在 J 的后面,并且紧挨着 J } until I > J; { 经过这样的一轮循环,此时 J 前面的元素全部都小于等于 P,J 后面的元素全部都大于等于 P,与 P 相等的元素(重复出现的元素,等 P 元素)会在 J 的前后换来换去,位置不定,不过没关系,将来 J 前面的一串元素(串1)会作为一个整体再次排序,那么与 P 相等的元素(等 P 元素)就会排在串后(串1的最后),而 J 后面的一串元素(串2)也会作为一个整体再次排序,那么与 P 相等的元素(等 P 元素)就会排在串前(串2的前面),这样两串元素(“串1”与“串2”)在 J 的位置相连接,就把所有与 P 相等的元素(等 P 元素)连在一起了 } { L < J 表示 J 前面还有元素需要排序,这些元素也就是上面所说的小于 P 的元素,(也就是“串1”) } { 递归调用 QuickSort 函数对“串1”进行排序 } if L < J then QuickSort(SortList, L, J, SCompare); { 经过一层或多层递归处理后,“串1”已经被全部排序完毕,接下来就要处理 J 后面的元素了,也就是“串2” } { 此时 I 刚好在 J 的后面紧挨着 J,所以从 I 开始后面元素的为“串2” } { 将 I 作为范围的起始位置,范围的结束位置不变,继续处理“串2” } L := I; { 直到 I 走到整个数组的最后,表示再没有元素需要被移动 } until I >= R; { 此时,整个指针数组排序完毕 } end; 个人能力有限,理解难免有偏差,如果有更好的解释,欢迎批评指正!
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值