算法导论——(1)加权中位数的实现

来源:互联网 发布:mac 符号 编辑:程序博客网 时间:2024/05/17 05:54

加权中位数

这是算法导论9-2的习题大概意思是有一个无序集合,这个集合中的所有元素都带有有一个权重,权重之和为1。例如权重集合为w[]={0.1,0.35,0.05,0.1,0.15,0.05,0.2};元素集合为x[]={4,3,12,8,7,6,5.2};
所谓加权中位数的意思就是找到一个元素X,使得大于X的所有元素的权重值加起来小于等于0.5,小于X的元素权重加起来小于0.5。

大致思路是这样的:
1.利用快速排序的方法,每次partition()找到一个分割点i,使得小于索引【i】的结点的元素值x都小于nodes[i]的x值。大于【i】的索引的结点的袁素志都比【i】结点的x大。
2.当我们得到一个i时,我们就调用getSum()计算i左右两边的权重之和的大小。
3.当左边的权重之和小于0.5,右边的权重之后小于等于0.5时,满足加权中位数的定义,返回【i】;
4,当不满足条件时,判断左边的权重是否大于右边的权重,如果大于,则说明,加权重中位数一定是在【i】的左边,递归调用findMidNumer(nodes,p,i-1);
否则说明在【i】的右边,调用findMidNumber(nodes,i+1,q);

以下为代码:

package Algorithm;import java.util.Random;public class JiaQuanMidNumer {    //定义一个类来存权值和元素信息    static class Node{        double w;        double x;        public Node(double w,double x){            this.w=w;            this.x=x;        }        public void set(double w,double x){            this.w=w;            this.x=x;        }    }    //计算这段区间的权重之和    public static double getSum(Node[] nodes,int p,int q){        double result=0;        for(int i=p;i<=q;i++){            result=result+nodes[i].w;        }        return result;    }    //交换两个结点的元素和权重的值    public static void swap(Node p,Node q){        double x=p.x;        double w=p.w;        p.set(q.w,q.x);        q.set(w,x);    }    public static int partition(Node[] nodes,int p,int q){        if(p<q){            int i=p-1;            Random r=new Random();            int rnum=r.nextInt(q-p)+p;            swap(nodes[q],nodes[rnum]);            for(int j=p;j<q;j++){                if(nodes[j].x<nodes[q].x){                    i++;                    swap(nodes[i],nodes[j]);                }            }            swap(nodes[i+1],nodes[q]);            return i+1;        }        return 0;    }    public static  int findMidNumber(Node[] nodes,int p,int q){        if(p==q) return q;        if(p<q){            int i=partition(nodes,p,q);            double l=getSum(nodes,0,i-1);            double r=getSum(nodes,i+1,nodes.length-1);            if(l<0.5&&r<=0.5)                return i;            else if(l<r){                return findMidNumber(nodes,i+1,q);            }            else{                return  findMidNumber(nodes,p,i-1);            }        }        return 0;    }    public static void main(String args[]){        Node[] nodes=new Node[7];        double w[]={0.1,0.35,0.05,0.1,0.15,0.05,0.2};        double x[]={4,3,12,8,7,6,5.2};        for(int i=0;i<w.length;i++)            nodes[i]=new Node(w[i],x[i]);        int i=findMidNumber(nodes,0,nodes.length-1);        System.out.println("进行快排选择后的序列为:");        System.out.print("w:");        for(int j=0;j<nodes.length;j++){            System.out.print("   "+nodes[j].w);        }        System.out.println();        System.out.print("x:");        for(int j=0;j<nodes.length;j++){            System.out.print("   "+nodes[j].x);        }        System.out.println();        System.out.println("进行快排选择后的加权中位数下标为(0,1,...):"+i+"  加权中位数为:"+nodes[i].x);    }}
0 0
原创粉丝点击