基于快速选择算法解决求中位数问题

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:xArray[nm],iIndexl, jIndexr+1 ifIndexl>=Indexrthen returnArray[Indexl] do ii+1 whileArray[i]<x do jj1 whileArray[j]>x ifi>=jthen break endwhile ifjIndexl+1==nmthen returnArray[j] endif Array[Indexl]Array[j] Array[j]x ifjIndexl+1<nmthen QuitSort{j+1,Indexr,nmj+Indexl+1} else QuitSort{Indexl,j1,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;
	}
	 


  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值