Algorithm 选择算法查找中间值,元素向左和向右

Algorithm 选择算法查找中间值,元素向左和向右,algorithm,Algorithm,假设我有一个大小为n的未排序数组 如何找到n/2,n/2−1,n/2+1线性时间内原始未排序列表中的最小元素 我尝试在中使用选择算法(我正在实现基于分区的通用选择算法) 函数分区(列表、左、右、数据透视索引) 数据透视值:=列表[数据透视索引] 交换列表[数据透视索引]和列表[右]//将数据透视移动到末尾 storeIndex:=左 对于i,从左到右-1 如果列表[i]

假设我有一个大小为n的未排序数组

如何找到n/2,n/2−1,n/2+1线性时间内原始未排序列表中的最小元素

我尝试在中使用选择算法(我正在实现基于分区的通用选择算法)

函数分区(列表、左、右、数据透视索引)
数据透视值:=列表[数据透视索引]
交换列表[数据透视索引]和列表[右]//将数据透视移动到末尾
storeIndex:=左
对于i,从左到右-1
如果列表[i]<数据透视值
交换列表[storeIndex]和列表[i]
增量存储索引
交换列表[right]和列表[storeIndex]//将pivot移动到其最终位置
返回存储索引
功能选择(列表、左、右、k)
if left=right//如果列表仅包含一个元素
return list[left]//返回该元素
在左和右之间选择pivotIndex//我应该选择什么样的pivotIndex值??????????
pivotNewIndex:=分区(列表、左、右、pivotIndex)
pivotDist:=pivotNewIndex-左+1
//枢轴处于其最终排序位置,
//所以,若列表已排序,pivotDist将反映其基于1的位置
如果pivotDist=k
返回列表[pivotNewIndex]
如果k
但我还不明白3到4个步骤。我有以下疑问:

  • 我是否选择了正确的算法,它是否真的能在线性时间内为我的程序工作。我有点困惑,因为它类似于快速排序
  • 调用函数时,从主函数中选择left、right和k的值。考虑我的数组是列表[1…n]。< /LI>
  • 我是否必须调用select函数三次,一次用于查找第n/2个最小值,另一次用于查找第n/2+1个最小值,另一次用于查找第n/2-1个最小值,或者可以在一次调用中完成,如果是,如何完成
  • 此外,在函数选择(第三步)“选择左和右之间的数据透视索引”中,我应为我的程序/目的选择数据透视索引的值

  • 谢谢

    它类似于快速排序,但它是线性的,因为在快速排序中,您需要同时处理轴的左侧和右侧,而在快速选择中,您只处理轴的一侧

    如果
    N
    为奇数,则初始调用应为
    Select(A,0,N,(N-1)/2)
    ;如果
    N
    为偶数,您需要准确地决定要做什么

    要查找中间值和左/右,您可能需要调用它来查找中间值,然后只需计算数组左侧组件的最大值和右侧组件的最小值,因为您知道,一旦完成中间值选择阶段,中间值左侧的所有元素都将小于它,右侧的所有元素都将大于(或等于)。这是O(n)+n/2+n/2=O(n)总时间

    有很多方法可以选择轴心指数。出于偶然的目的,中间元素或随机索引可能就足够了

    function partition(list, left, right, pivotIndex)
     pivotValue := list[pivotIndex]
     swap list[pivotIndex] and list[right]  // Move pivot to end
     storeIndex := left
     for i from left to right-1 
         if list[i] < pivotValue
             swap list[storeIndex] and list[i]
             increment storeIndex
     swap list[right] and list[storeIndex]  // Move pivot to its final place
     return storeIndex
    
    
    function select(list, left, right, k)
     if left = right // If the list contains only one element
         return list[left]  // Return that element
     select pivotIndex between left and right //What value of  pivotIndex shud i select??????????
     pivotNewIndex := partition(list, left, right, pivotIndex)
     pivotDist := pivotNewIndex - left + 1 
     // The pivot is in its final sorted position, 
     // so pivotDist reflects its 1-based position if list were sorted
     if pivotDist = k 
         return list[pivotNewIndex]
     else if k < pivotDist 
         return select(list, left, pivotNewIndex - 1, k)
     else
         return select(list, pivotNewIndex + 1, right, k - pivotDist)