选择算法是一种用于在列表或数组中找到第k个最小(或最大)数的算法。该数字称为k阶统计量。它包括在列表或数组中查找最小,最大和中位数元素的各种情况。为了通过遍历列表来查找最小(或最大)元素,我们会跟踪到目前为止出现的当前最小(或最大)元素,并且与选择排序有关。
下面是选择无序列表中第k个最小(或最大)元素的不同方法:
- 排序选择
对列表或数组进行排序,然后选择所需的元素可以使选择变得容易。该方法对于选择单个元素效率不高,但是在需要从仅需要对数组排序的数组中进行许多选择时,效率很高。即使由于缺乏随机访问而对链表进行了排序,链表中用于选择的也是O(n)。
代替对整个列表或数组进行排序,我们可以使用部分排序来选择列表或数组中的第k个最小(或最大)元素。然后,第k个最小(或最大)的元素是部分排序列表中最大(或最小)的元素。这需要O(1)来访问数组,而O(k)则需要访问列表。- 无序部分排序
无序部分排序是一种排序算法,其中第一个k元素处于排序顺序,其余k个元素处于随机顺序。用于查找第k个最小(或最大)元素。时间复杂度降低到O(k log k) 。但是由于K≤n,所以渐近时间复杂度收敛到O(n) 。
注意:由于元素可能相等,因此在对列表或数组进行排序时,不得包含小于或等于第k个元素的元素,因为大于第k个元素的元素也可能等于第k个最小元素。 - 部分选择排序
选择排序中使用的概念可帮助我们对数组进行部分排序,最多排序第k个最小(或最大)的元素,以查找数组中第k个最小(或最大)的元素。因此,部分选择排序会产生一种简单的选择算法,该算法需要O(k * n)时间对数组进行排序。这在渐近效率上是无效的,但是如果k小并且易于实现,则可以足够有效。
以下是部分选择排序的算法:function partialSelectionSort(arr[0..n], k) { for i in [0, k) { minIndex = i minValue = arr[i] for j in [i+1, n) { if (arr[j] < minValue) then minIndex = j minValue = arr[j] swap(arr[i], arr[minIndex]) } } return arr[k] }
- 无序部分排序
- 基于分区的选择
对于基于分区的选择,使用快速选择算法。它是快速排序算法的一种变体。在这两种方法中,我们都选择一个枢轴元素,并使用quicksort算法中的划分步骤将所有小于枢轴的元素排列在其左侧,将大于枢轴的元素排列在其右侧。
但是,虽然Quicksort在分区的两侧递归,但Quickselect仅在一侧出现,即需要的第k个元素的一侧递归。
基于分区的算法就位,这导致对数据进行部分排序。通过不以O(n)辅助空间为代价来更改原始数据,可以在不适当的位置进行处理。 - 中位数被选作枢轴
通过选择数组的中位数作为Quickselect或Quicksort算法中的枢轴元素,中位数选择算法可用于执行选择算法或排序算法。
在实践中,枢轴计算的开销非常大,因此通常不使用这些算法,但是该技术在关联选择和排序算法方面具有理论意义。
数组的中位数是对数组进行排序的最佳枢轴,因为它可以将数据均匀地分为两部分,从而在选择算法为最佳的情况下保证了最佳的排序。