Hoare 分区算法详解

给定一个数组 arr[],我们的任务是以第一个元素作为枢轴来对数组进行分区

数组的分区必须满足以下两个条件:

  • 小于枢轴元素的元素必须出现在小于或等于分区索引的位置。
  • 大于或等于枢轴元素的元素必须出现在大于分区索引的位置。

分区索引等于严格小于枢轴的元素个数减一。
注意:可能存在不止一种满足条件的分区结果。
示例

> 输入: arr[] = [5, 3, 8, 4, 2, 7, 1, 10]

> 输出: [1, 3, 2, **4**, 8, 7, 5, 10]

> 解释: 分区索引为 3,枢轴元素是 5。所有小于枢轴的元素 [1, 3, 2, 4] 被安排在分区索引之前,而大于或等于枢轴的元素 [8, 7, 5, 10] 被安排在分区索引之后。

>

> 输入: arr[] = [12, 10, 9, 16, 19, 9]

> 输出: [9, 10, **9**, 16, 19, 12]

> 解释: 分区索引为 2,枢轴元素是 12。所有小于枢轴的元素 [9, 10, 9] 被安排在分区索引处或之前,而大于或等于枢轴的元素 [16, 19, 12] 被安排在分区索引之后。

目录

  • Hoare 数组分区算法
  • 一些有趣的事实

Hoare 数组分区算法

> Hoare 分区算法是一种围绕枢轴对数组进行分区的有效方法。它基于双指针技术,这两个指针从数组的两端开始并向彼此移动,直到找到需要交换的元素。

让我们逐步解析这个算法:

  • 将第一个元素视为枢轴,并初始化两个指针,INLINECODE3df1cd49 在数组开头,INLINECODEa6052049 在数组末尾。
  • 向右移动 INLINECODE77f9b674 直到找到大于或等于枢轴的元素,向左移动 INLINECODE0037498f 直到找到小于或等于枢轴的元素。
  • 如果 INLINECODE3a8b46cb 指向的元素大于或等于枢轴,且 INLINECODE236e25ad 指向的元素小于或等于枢轴,则交换它们。
  • 重复此过程,不断移动 INLINECODEd7e04682INLINECODEa2658d60 使它们彼此靠近,直到它们相遇或交叉。
  • 当指针交叉时,分区完成,左边是小于或等于枢轴的元素,右边是大于或等于枢轴的元素。

C++


CODEBLOCK_00509231

C


CODEBLOCK_ad238a4b

Java


CODEBLOCK_cd22f5bc

Python


CODEBLOCK_68c448fd

C#


CODEBLOCK_1341318b

JavaScript


CODEBLOCK_45303cfb

一些有趣的事实

  • 比 Lomuto 分区更高效:Hoare 分区通常比 Lomuto 分区方案快 3 倍,因为它平均进行的交换次数更少。Lomuto 分区会对每个小于枢轴的元素进行交换,而 Hoare 分区只在必要时交换(当左侧元素大于枢轴且右侧元素小于枢轴时)。
  • 指针移动方式:在 Hoare 的方案中,两个指针从两端向中间移动,而 Lomuto 方案只使用一个从左到右移动的指针。
  • 枢轴的最终位置:与 Lomuto 分区不同(枢轴保证被放置在其最终排序位置),Hoare 分区将枢轴元素放置在其正确的排序位置。当指针交叉时,枢轴元素可能与某些其他元素交换。不过,这并不影响快速排序的正确性,因为我们只是确保了数组已经被分为两个部分,然后递归处理即可。
  • 处理重复元素:Hoare 分区算法能更高效地处理数组中存在大量重复元素的情况,因为它会跳过相等的元素,减少了不必要的交换。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/51500.html
点赞
0.00 平均评分 (0% 分数) - 0