1. 求解中位数思路
1.给定一组数据,如果是人类算中位数也是要先排序,但在程序中最快的快排算法时间复杂度也达到了nlogn,这是目前最低复杂度的一类排序。
2.快速选择找到中位数
1.首先要明确中位数的一个特性:给定一串数列,比中位数项小的项的个数一定等于比中位数项大的项的个数(不考虑偶数项时求平均的情况)。
2.类似快排,选择一个枢纽,每个小步把比枢纽小的项放在枢纽左边,比枢纽大的项放在枢纽右边,每小步排序完成后都验证一下是不是被选择的枢纽处于整个数列中央,如果是那么就是要找的中位数;如果不是整个数列中央:枢纽的序号如果比中央索引小,说明真正的中位数应该在当前所选枢纽的右边,则对右边部分进行快速选择;同理,枢纽的序号如果比中央索引大,说明真正的中位数应该在当前所选枢纽的左边,则对左边部分进行快速选择。
3. 算法描述
A l g o r i t h m Q u i c k S o r t I n p u t : A r r a y , I n d e x l , I n d e x r , n m O u t p u t : K m i d I n i t i a l i z a t i o n : x ← A r r a y [ n m ] , i ← I n d e x l , j ← I n d e x r + 1 i f I n d e x l > = I n d e x r t h e n r e t u r n A r r a y [ I n d e x l ] d o i ← i + 1 w h i l e A r r a y [ i ] < x d o j ← j − 1 w h i l e A r r a y [ j ] > x i f i > = j t h e n b r e a k e n d w h i l e i f j − I n d e x l + 1 = = n m t h e n r e t u r n A r r a y [ j ] e n d i f A r r a y [ I n d e x l ] ← A r r a y [ j ] A r r a y [ j ] ← x i f j − I n d e x l + 1 < n m t h e n Q u i t S o r t { j + 1 , I n d e x r , n m − j + I n d e x l + 1 } e l s e Q u i t S o r t { I n d e x l , j − 1 , n m } e n d i f \begin{array}{cc} \hline \\ Algorithm Quick Sort \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\,\\ \hline \\ \ { \text Input{: Array, Index_l, Index_r, n_m} \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\,} \\ \ { \text Output: K_{mid} \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,}\\ \ {Initialization: x\leftarrow Array[n_m], \, i\leftarrow Index_l, \,} \\ \ { j \leftarrow Index_r+1 }\\ \ {if \, \, Index_l >= Index_r \, \, then\,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, }\\ \ {return \, \, Array[Index_l]\,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,\, \,} \\ \ {do \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad }\\ \ {i\leftarrow i+1 \qquad \qquad \qquad \qquad \qquad \qquad }\\ \ {while \,\,Array[i]<x \qquad \qquad \qquad \qquad}\\ \ {do \qquad \qquad \qquad \qquad \qquad \qquad \qquad\qquad\qquad}\\ \ { j \leftarrow j-1\qquad\qquad\qquad\qquad\qquad\qquad}\\ \ {while \,\,Array[j]>x \qquad \qquad \qquad \qquad}\\ \ {if \,\,i>=j then\qquad\qquad\qquad\qquad\qquad\qquad}\\ \ {break\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad}\\ \ {end while \qquad\qquad\qquad\qquad\qquad\qquad\qquad}\\ \ if \,\, j- Index_l +1==n_m then\\ \ {return \,\,Array[j]}\\ \ {end \,\,if}\\ \ {Array[Index_l] \leftarrow Array[j]}\\ \ {Array[j] \leftarrow x}\\ \ {if \,\, j-Index_l+1<n_m \,\,then}\\ \ {Quit Sort\lbrace j+1,Index_r,n_m-j+Index_l+1\rbrace}\\ \ {else}\\ \ {Quit Sort\lbrace Index_l,j-1,n_m\rbrace}\\ \ {end \,\, if}\\ \hline \\ \end{array} AlgorithmQuickSort Input:Array,Indexl,Indexr,nm Output:Kmid Initialization:x←Array[nm],i←Indexl, j←Indexr+1 ifIndexl>=Indexrthen returnArray[Indexl] do i←i+1 whileArray[i]<x do j←j−1 whileArray[j]>x ifi>=jthen break endwhile ifj−Indexl+1==nmthen returnArray[j] endif Array[Indexl]←Array[j] Array[j]←x ifj−Indexl+1<nmthen QuitSort{j+1,Indexr,nm−j+Indexl+1} else QuitSort{Indexl,j−1,nm} endif
4. C++描述
#include <bits/stdc++.h>
using namespace std;
int arr[50];
int select(int left,int right,int k) //管道的纵坐标应该是所有油井的纵坐标的中位数
{
if( left >= right )
return arr[left];
int x = arr[left];
int i = left;
int j = right+1;
while(1)
{
do{
i++;
}while(arr[i]<x);
do{
j--;
}while(arr[j]>x);
if( i>=j )
break;
std::swap(arr[i],arr[j]);
}
if( j-left+1 == k )
return x;
arr[left] = arr[j];
arr[j] = x;
if( j-left+1 < k )
return select(j+1,right,k-j+left-1);
else
return select(left,j-1,k);
}
int main()
{
int x;
int y;
int n;
cin >> n;
for(int i=0; i<n; i++)
{
cin >> x >>arr[i];
}
y=select(0,n-1,n/2); //求中位数
int min=0;
for(int i=0; i<n; i++)
{
min+=(int)fabs(arr[i]-y);
}
cout << min;
return 0;
}