`
flyingdutchman
  • 浏览: 353408 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

取中位数的算法

阅读更多
        找出一个组元素中的中位数(中间值,它不大于一半的元素也不小于另一半的元素),是一个和排序有关但又不需要完全排序的重要应用。查找中位数在统计和许多数据处理中很常见。
        可以把查找中位数看成是一种特殊的选择:在数组中查找第k个小或大的元素。我们可以回想前面《快速排序及改进》中的partition(Comparable[] a,int lo,int hi)方法,它会将数组的a[lo]到a[hi]重新排列(局部排序)并返回一个整数j,使得:
             a[lo ... j - 1] <= a[j] <= a[j + 1 ... hi]
        

那么,要获取第K小的值,当k = j时,a[j]就是要求解的数值了。
        /**
         *查找一个数组中的第k小的元素
         */
        public static Comparable select(Comparable[] a,int k){
           //对数组a洗牌
           shuffle(a);
           int lo = 0;
           int hi = a.length - 1;
           int j = 0;
           while(hi > lo){
              j = partition(a,lo,hi - 1);
              if(j == k){
                 return a[k];
              }else if(j > k){
                 hi = j - 1;
              }else{
                 lo = j + 1;
              }
           }
           return a[k];
        }
        
       
        对于查找中位数,就是k = N/2时的a[j],a[j]就是要求的中位数。整个代码如下:
 /**
  * 取中位数
  */
 public class MedianFinder extends SortBase{
       
	
	      /**
	       * 局部排序,查找数组a的中位数
	       * @param a
	       * @return
	       */
       public static Comparable find(Comparable[] a){
              int len = a.length;              
    	      int mid = 0;
              if((isOdd(len)){//奇数
                  mid = (len + 1)/2;                  
              }else{
                  mid = len/2;
              }
              return select(a,mid - 1);   	      
       }
       
       /**
        * 判断整数i是否是奇数
        * @param i
        * @return true:奇数,false:偶数
        */
       private static isOdd(int i){
             return (k & 1) != 0;
       }
    
       /**
        * 查找数组a中第k小的元素
        * @param a
        * @param k
        * @return
        */
        public static Comparable select(Comparable[] a,int k){
    	      shuffle(a);
    	      Comparable val = null;
    	      int lo = 0;
    	      int hi = a.length - 1;
    	      int j = 0;
    	      while(hi > lo){
    		  j = partition(a,lo,hi);
    		  if(j == k){
    			val = a[k];
    			break;
    		  }else if(j > k){
    			hi = j - 1;
    		  }else{
    			lo = j + 1;
    		  }
    	      }
    	      return val;
        }
    
         /**
	    * 在数组a的下标lo和hi范围内获取快速切分的基数的小标,使该基数的左边的
	    * 元素都不大于该数,而右边的元素都不小于该数
	    * @param a
	    * @param lo
	    * @param hi
	    * @return 快速切分基数的下标
	    */
	   public static int partition(Comparable[] a,int lo,int hi){
		  //将数组切分为a[lo...i - 1],a[i],a[j + 1,hi]
		  int i = lo,j = hi + 1;   //设置左右扫描指针
		  Comparable v = a[lo];    //切分元素
		  while(true){
			while(less(a[++i],v)){
				if(i == hi) break;
			}
			while(less(v,a[--j])){
				if(j == lo) break;
			}
			if(i >= j){
				break;
			}
			exch(a,i,j);
		  }
		  exch(a,lo,j); //将v = a[i]放入正确的位置
		  //a[lo...j - 1] <= a[j] <= a[j + 1 ... hi]
		  return j; 
	   }
 }
        
分享到:
评论

相关推荐

    贪婪算法的代码

    }/********寄存器中的所有数右移一位*****/ /***************打印缺页数和缺页率**********************/ printf("the count of Exchanged is: %d \n",count); printf("the rate of exchanged is: %f\n",count*...

    算法导论(part1)

    第9章 中位数和顺序统计学 9.1 最小值和最大值 9.2 以期望线性时间做选择 9.3 最坏情况线性时间的选择 第三部分 数据结构 引言 第10章 基本数据结构 10.1 栈和队列 10.2 链表 10.3 指针和对象的实现 ...

    RSA加密算法C语言实现

    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。 RSA的算法涉及三个参数,n、e1、e2。 其中,n是两个大质数p、q的积,n的二进制表示时所占用的...

    C/C++常用算法手册.秦姣华(有详细书签).rar

    9.10.2 计算平方回文数算法 297 9.11 分解质因数 299 9.12 小结 301 第10 章算法经典趣题 302 0. .l 百钱买百鸡 302 10.1.1 百钱买百鸡算法 302 10.1.2 百钱买百鸡求解 303 10.2 五家共井 304 10.2.1 五家...

    十种排序算法介绍

    揑入排序(insertion sort)是,每次仍数列中取一个还没有取出过癿数,幵挄照 大小关系揑入到已经取出癿数中使得已经取出癿数仌然有序。冒泡排序(bubble sort)分为若干趟迚行,每一趟排 序仍前往后比较每两个相邻癿...

    数据结构与算法

    中位数与第 小元素……………… 平均情况下的线性时间选择 算法 ……………………………… 最坏情况下的线性时间选择 算法 ……………………………… 应用 …………………………………… 本章小结 ……………………...

    算法导论 第二版 (完整版)

    第9章 中位数和顺序统计学 第三部分 数据结构 第10章 基本数据结构 第11章 散列表 第12章 二叉查找树 第13章 红黑树 第14章 数据结构的扩张 第四部分 高级设计和分析技术 导论 第15章 动态规划 第16章 贪心算法 第17...

    网际校验和算法VC源码

    计算这些校验和的算法称为网际校验和算法,简单来说就是:把被校验的数据16位进行累加,然后取反码,若数据字节长度为奇数,则数据尾部补一个字节的0以凑成偶数。 由于从输入文件读入的数据不能直接满足计算校验和的...

    算法导论(part2)

    第9章 中位数和顺序统计学 9.1 最小值和最大值 9.2 以期望线性时间做选择 9.3 最坏情况线性时间的选择 第三部分 数据结构 引言 第10章 基本数据结构 10.1 栈和队列 10.2 链表 10.3 指针和对象的实现 ...

    算法导论(第二版 中文高清版)

    第9章 中位数和顺序统计学 第三部分 数据结构 第10章 基本数据结构 第11章 散列表 第12章 二叉查找树 第13章 红黑树 第14章 数据结构的扩张 第四部分 高级设计和分析技术 导论 第15章 动态规划 第16章 贪心算法 第17...

    古典密码的移位算法及置换算法

    维吉尼亚密码 首先确定密钥长度(本例中密钥只采取个位数字,所以取决于输入密钥的长度),然后输入满足这个长度的向量;加密:取明文第一个字母并将之移k1位,这里k1=1,第二个字母移k2位,k2=2,一旦到了密钥末尾,...

    算法导论 第二版

    第9章 中位数和顺序统计学 第三部分 数据结构 第10章 基本数据结构 第11章 散列表 第12章 二叉查找树 第13章 红黑树 第14章 数据结构的扩张 第四部分 高级设计和分析技术 导论 第15章 动态规划 第16章 贪心算法 第17...

    常用算法代码

    | 所有数位相加 25 Number 数论 26 1 |递推求欧拉函数 PHI(I) 26 |单独求欧拉函数 PHI(X) 26 | GCD 最大公约数 26 | 快速 GCD 26 | 扩展 GCD 26 | 模线性方程 A * X = B (% N) 26 | 模线性方程组 26 | ...

    易语言经典算法

    易语言经典算法:1. 取所有质数 2. 求最小公倍数 3. 求最大公约数 4. 汉诺塔 5. 9X9乘法表 6. 猫捉老鼠(筛选法) 7. 水仙花数问题 8. 计算组合 9. 身份证升级15位升级到18位 10. 用冒泡法排序数字 11. 九宫计算 12. ...

    基于位图的n选m的组合算法实现(C#)

    基于C# 实现的组合算法,可实现对任意类型的数据进行n选m的组合, 比如数字,字符串,对象等。 n必须大于0小于Int.MaxValue

    数据结构与算法.xmind

    每次选择最大的数插入到末尾中 做法 外层for循环控制次数 内层for循环找出最大的值的角标 找出最大角标后,进行交换 优化思路 同时获取最大值和最小值,然后分别...

    在Rust 中实现的 RSA算法_rust_代码_下载

    (提高性能(仍然取决于随机性和 Prime 接近度)) 使用 AES-128/256(待确定)实施混合加密过程。 在开始计算算法之前,通过丢弃 [3, 5, 7, 9, 11, 13, 15, 19] 的倍数来优化 Rabin-Miller 算法。(提高性能) 并行...

    子网掩码、子网数及主机数的算法

    与15最近的2^x是16(2^4),但16个主机块,实际只用14个可用,不能满足本题15个主机块的条件,故取32(2^5),所以子网数为2^(8-5=3)是8个,实际可用子网数为6,子网掩码为255.255.255.224(256-32)。

    可视化算法程序-RSA-课设

    附录中给出了证明a=c (mod n). 对软件的要求总结如下: ①可以按要求的位数生成非对称密钥。 ②可以用指定密钥以RSA算法加密任意一个文件,加密生成的数据为纯文本。 ③可以装载加密过的文件,并用指定的密钥解密...

Global site tag (gtag.js) - Google Analytics