📜  选择算法

📅  最后修改于: 2021-05-06 19:11:25             🧑  作者: Mango

选择算法是一种用于在列表或数组中找到第k个最小(或最大)数的算法。该数字称为k阶统计量。它包括在列表或数组中查找最小,最大和中位数元素的各种情况。为了通过遍历列表来查找最小(或最大)元素,我们会跟踪到目前为止出现的当前最小(或最大)元素,并且与选择排序有关。
下面是选择无序列表中第k个最小(或最大)元素的不同方法:

  1. 排序选择
    对列表或数组进行排序,然后选择所需的元素可以使选择变得容易。该方法对于选择单个元素效率不高,但是在需要从仅需要对数组排序的数组中进行许多选择时,效率很高。即使由于缺乏随机访问而对链表进行了排序,链表中用于选择的也是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]
      }
      
  2. 基于分区的选择
    对于基于分区的选择,使用快速选择算法。它是快速排序算法的一种变体。在这两种方法中,我们都选择一个枢轴元素,并使用quicksort算法中的划分步骤将所有小于枢轴的元素排列在其左侧,将大于枢轴的元素排列在其右侧。
    但是,虽然Quicksort在分区的两侧递归,但Quickselect仅在一侧出现,即需要的第k个元素的一侧递归。
    基于分区的算法就位,这导致对数据进行部分排序。通过不以O(n)辅助空间为代价来更改原始数据,可以在不适当的位置进行处理。
  3. 中位数被选作枢轴
    通过选择数组的中位数作为Quickselect或Quicksort算法中的枢轴元素,中位数选择算法可用于执行选择算法或排序算法。
    在实践中,枢轴计算的开销非常大,因此通常不使用这些算法,但是该技术在关联选择和排序算法方面具有理论意义。
    数组的中位数是对数组进行排序的最佳枢轴,因为它可以将数据均匀地分为两部分,从而在选择算法为最佳的情况下保证了最佳的排序。