中值排序的java实现

public class MidSort {
    public static void main(String[] args){
        int[] arr={1,3,5,7,2,4,6,8,9};
        midSort(arr,0,7);
        for(int i:arr){
            System.out.print(i + " ");
        }
        System.out.println();
    }

    //返回数组被中值分成两堆后中值所在位置
    public static int partition(int[] goal,int left,int right,int midPos){//left和right是为位置指示,表明你要排序的是
        // 数组的那部分,否则要把待排序的数组切割出来
        int mid=goal[midPos];
        int tmp,idx;
        //把中值移到数组末尾
        tmp=goal[right];
        goal[right]=goal[midPos];
        goal[midPos]=tmp;

        int smallPos=left;//指向比中值小的,每当有比中值小的数把它放入smallPos所指地方,然后smallPos+1,这样保证
                       //smallPos指过的位置都放着比中值小的(也就是在最前面的那些)
        for(idx=left;idx<right;idx++){
            if(goal[idx]<mid){//每当有比中值小的数把它放入smallPos所指地方,从而把小于中值的移到前面去
                tmp=goal[idx];
                goal[idx]=goal[smallPos];
                goal[smallPos]=tmp;
                smallPos++;
            }
        }
        //把中值放回它应该在的位置
        tmp=goal[right];
        goal[right]=goal[smallPos];
        goal[smallPos]=tmp;
        return smallPos;//返回中值所在位置
    }

    //因为选值来作为中值是随机的(有时是以第一个来作为),所以被分成两堆的数组可能不均衡,所有找出第k(此时k=(length+1)/2)
    // 便使分堆后的数组平衡了)大的元素的位置
    public static int selectKth(int[] goal,int left,int right, int k){//返回第K大元素
        int midPos=selectMidPos(goal,left,right);//返回作为中值的为元素的位置,若是选数组第一个作为中值时有时会让性能
                                                 //退化成O(n的平方)(如它是最大、小值时,分堆后会有一堆为空),要避免
                                                 //会在数组中随机选一个作为中值
        int pos=partition(goal,left,right,midPos);//数组被中值分成两堆后中值所在位置
        if(pos==k+left-1){//说明真正想要作为分堆的中值恰好就是之前选定分堆的中值
            return pos;
        }else if(k+left-1<pos){//小于,如k是第4大,之前是第3大,所以小于,继续分堆直到返回k为止因为此时数组才按k作为中值来分堆
                        //所以第K大元素在在之前分好堆中的左边那堆,它在这堆是第k-pos大
            return selectKth(goal,left,pos-1,k);
        }else{//大于,所以第K大元素在在之前分好堆中的右边那堆,它在这堆是第k大
            return selectKth(goal,pos+1,right,k-(pos-left+1));
        }
    }

    public static void midSort(int[] goal,int left,int right){
        if (left>=right)return;//如果只有一个元素或更少
        int mid=(right-left+1)/2;
        int midPos=selectKth(goal,left,right,mid+1);//得到能把数组分为平均两堆的中值的位置且此时已分好堆
        midSort(goal,left,left+mid-1);              //对左边这堆继续分堆
        midSort(goal,left+mid+1,right);             //对右边这堆继续分堆
    }

    public static int selectMidPos(int[] goal,int left,int right){
        //随机选定中值
        int distant =right-left+1;
        int random=(int)Math.round(Math.random()*distant);
        int pos=random+left<=right?random+left:random+left-1;
        return pos;

    }

}
时间: 2024-08-11 05:43:34

中值排序的java实现的相关文章

Java--&gt;吧把txt中的所有字符按照码表值排序

--> List 列表中的自动添加的多余空间长度该怎么去除呢?... package com.dragon.java.filesort; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /* * 将day19-

Map中按value值排序

大家都知道,在java中的集合Map中按键值key排序比较简单,只需引用集合TreeMap即可,可是怎样实现按value值排序呢?下面我们来测试一下: public class TestHashMap { public static void main(String[] args) { Map<String, Integer> map = new HashMap<String, Integer>(); map.put("zhangsan", 1); map.pu

Java中值类型和引用类型的区别

[定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变.值类型表示复制一个当前变量传给方法, 当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.通俗说法: 值类型就是现金,要用直接用:引用类型是存折,要用还得先去银行取现.----(摘自网上) [值类型] 也就是基本数据类型 基本数据类型常被称为四类八种 四类: 1,整型 2,浮点型 3,字符型4,逻辑型 八种: 1,整型3种 by

Java中值类型与引用类型

JAVA中值类型和引用类型的不同? 1.定义 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法是传入的变量的值也将改变:值类型表示复制一个当前变量传给方法,当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.通俗说法: 值类型就是现金,要用直接用:引用类型是存折,要用还得先去银行取现. 2.分类 (1)值类型 值类型也就是基本数据类型 基本数据类型常被称为四类八种. 四类:1.整型 2.浮点型 3.字符型4.逻辑

java中值类型和引用类型的不同实例(一)

简单分类,java中除了值类型就是对象.值类型就是java中的基本类型,而除了这些基本类型都是对象. [内存] “一个具有值类型(value type)的数据存放在栈内的一个变量中.即是在栈中分配内存空间,直接存储所包含的值,其值就代表数据本身. 值类型的数据具有较快的存取速度. 一个具有引用类型(reference type)的数据并不驻留在栈中,而是存储于堆中.即是在堆中分配内存空间,不直接存储所包含的值,而是指向所要存储的值,其值代表的是所指向的地址.当访问一个具有引用类型的数据时,需要到

java 中值传递和引用传递(转)

java中给函数传递参数的方式有两种:值传递和引用传递.一般而言,基本类型是值传递:引用类型是引用传递.但传值时到达发生了什么? 1.基本类型 8个基本类型(byte,short,int,long,float,double,char,boolean)是值传递. 1 public class ValueTest { 2 3 public static void main(String[] args) { 4 int a = 10; 5 changeVal(a); 6 System.out.prin

javascript中对两个对象进行排序 和 java中的两个对象排序

javascript中的对象数组排序 一 定义一个对象数组 var text = [{"name":"张","age":24},{"name":"秦","age":26},{"name":"刘","age":29},{"name":"司空","age":78},{&qu

Java集合中对象排序

集合中的对象排序需求还是比较常见的,当然我们可以重写equals方法,循环比较:同时Java为我们提供了更易使用的APIs.当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序. 下面通过两个例子分别用Comparable和Comparator实现对User对象中年龄排序. Comparable接口方式 类自身实现Comparable接口,实现该接口中的compareTo方法. import java.util.A

Comparable与Comparator,java中的排序与比较

1:比较和排序的概念 比较:两个实体类之间按>,=,<进行比较. 排序:在集合类中,对集合类中的实体进行排序.排序基于的算法基于实体类提供的比较函数. 基本型别都提供了默认的比较算法,如string提供了按字母进行比较,int提供了按整数大小进行比较. 2:Comparable与Comparator but,在软件开发的世界中,任何没有代码的堆概念都是耍流氓.所以,无论我们解释的多么完美,必须show me the code: 我们首先看这样一段代码: public class Collect