快速选择算法

快速选择算法

我们可以将快速排序算法稍作修改将其应用在选择问题上,该算法称为快速选择算法,复杂度O(NlogN),最坏情况为O(N^2)。令|A|为A中的元素个数,查找A中第k个最小元,算法步骤如下:

1)如果|A|=1,那么k=1,则将A中的元素作为答案返回

2)取A中一元素V,称为枢纽元。

3)将A-{V}分为两个不相交的集合:A1和A2,其中A1中的元素值小于等于V,A2中的元素值大于等于V

4)若k<=|A1|,那么第k个最小元必然在A1中,在这种情况下返回quciksort(A1,k).如果k=1+|A1|,那么枢纽元就是第K个元素,我们将其返回。否则第k个最小元就在|A2|中,它是A2中的第(k-|A1|-1)个最小元,则递归调用返回quicksort(A2,k-|A1|-1).

  #define Cutoff ( 10 )
        void
        Qselect( ElementType A[ ], int k, int Left, int Right )
        {
            int i, j;
            ElementType Pivot;

/* 1*/      if( Left + Cutoff <= Right )
            {
/* 2*/          Pivot = Median3( A, Left, Right );
/* 3*/          i = Left; j = Right - 1;
/* 4*/          for( ; ; )
                {
/* 5*/              while( A[ ++i ] < Pivot ){ }
/* 6*/              while( A[ --j ] > Pivot ){ }
/* 7*/              if( i < j )
/* 8*/                  Swap( &A[ i ], &A[ j ] );
                    else
/* 9*/                  break;
                }
/*10*/          Swap( &A[ i ], &A[ Right - 1 ] );  /* Restore pivot */

/*11*/          if( k <= i )
/*12*/              Qselect( A, k, Left, i - 1 );
/*13*/          else if( k > i + 1 )
/*14*/              Qselect( A, k, i + 1, Right );
            }
            else  /* Do an insertion sort on the subarray */
/*15*/          InsertionSort( A + Left, Right - Left + 1 );
        }

该算法结束时,第k小的元素就在数组中第k个位置。

猜你喜欢

转载自blog.csdn.net/Alatebloomer/article/details/80348463