java算法-分治算法排序

package suanfa.sort;



/**
分治算法
原理:两组扑克牌,假设都是排序好的,小牌在上面,那这两个排序就比较最上面的两张,吧其中最小的放到第三组,作为结果,直到两组牌其中一组全部取完,另一组剩下的放到第三组
分两个方法
分解方法:将数组二分为两个数组,然后各自一半继续拆分为两个数组,直到无法拆分(最后一组称为叶子),树状结构
归约方法:从最叶子吧两个数组合并为一个数组
经过测试 10万长度的数组需要 100毫秒 ,比插入排序快80倍,长度越大,差距越明显
 */
public class FenZhiSort {
    public static void main(String[] args) {
//      System.out.println(Arrays.toString(merge(new int[]{1,3,8,9}, new int[]{2,4,5,6,7,10})));
//      
//      
//      Node n = new Node(new int[]{3,6,1,4,2,100,99,89,56,32,11,10});
//      n.sort();
//      System.out.println(Arrays.toString(n.arr));

        int[] arr = new int[100000];
        for(int i=0;i<arr.length;i++){
            arr[i] = arr.length - i;
        }
        long start = System.currentTimeMillis();
        Node n = new Node(arr);
        n.sort();
        //System.out.println(Arrays.toString(n.arr));
        System.out.println("耗时:"+(System.currentTimeMillis()-start));
    }

    public static class Node{
        int[] arr;
        boolean isSort = false;
        Node left;
        Node right;
        public Node(int[] arr){
            this.arr = arr;
        }
        public void sort(){
            fenjie(this);
            sort(this);
        }

        public void sort(Node n){
            if(n == null || n.isSort){
                return;
            }
            if(n.left == null && n.right == null){
                return;
            }else if(n.left != null && n.right == null){
                if(n.left.isSort){
                    n.arr = n.left.arr;
                    n.isSort = true;
                    return;
                }else{
                    sort(n.left);
                }
            }else if(n.left == null && n.right != null){
                if(n.right.isSort){
                    n.arr = n.right.arr;
                    n.isSort = true;
                    return;
                }else{
                    sort(n.right);
                }
            }else{
                if(!n.right.isSort){
                    sort(n.right);
                }
                if(!n.left.isSort){
                    sort(n.left);
                }
                n.arr = merge(n.left.arr, n.right.arr);
                n.isSort = true;
            }
        }

        public void fenjie(Node n){
            if(n.arr == null || n.arr.length == 0){
                return;
            }
            if(n.arr.length == 1){
                n.left = new Node(n.arr);
                n.left.isSort = true;

                n.arr = null;
            }else if(n.arr.length == 2){
                n.left = new Node(new int[]{n.arr[0]});
                n.left.isSort = true;

                n.right = new Node(new int[]{n.arr[1]});
                n.right.isSort = true;
                n.arr = null;
            }else if(n.arr.length%2==0){
                n.left = new Node(new int[n.arr.length/2]);
                n.right = new Node(new int[n.arr.length/2]);
                for(int i=0;i<n.arr.length/2;i++){
                    n.left.arr[i] = n.arr[i];
                    n.right.arr[i] = n.arr[n.arr.length-i-1];
                }
                fenjie(n.left);
                fenjie(n.right);
                n.arr = null;
            }else{
                n.left = new Node(new int[n.arr.length/2+1]);
                n.right = new Node(new int[n.arr.length/2]);
                for(int i=0;i<n.arr.length/2+1;i++){
                    n.left.arr[i] = n.arr[i];
                    if(i != n.arr.length-i-1){
                        n.right.arr[i] = n.arr[n.arr.length-i-1];
                    }
                }
                fenjie(n.left);
                fenjie(n.right);
            }
        }
    }

    public static int[] merge(int[] arr1,int[] arr2){
        int[] arr3 = new int[arr1.length+arr2.length];
        int i=0;
        int i1=0;
        int i2=0;
        while(true){
            if(!hasNext(arr1,i1)){
                for(int k=i2;k<arr2.length;k++){
                    arr3[i++] = arr2[k];
                }
                break;
            }else if(!hasNext(arr2,i2)){
                for(int k=i1;k<arr1.length;k++){
                    arr3[i++] = arr1[k];
                }
                break;
            }else if(arr1[i1]>arr2[i2]){
                arr3[i++] = arr2[i2++];
            }else{
                arr3[i++] = arr1[i1++];
            }
        }
        return arr3;
    }

    public static boolean hasNext(int[] arr,int i){
        return i<=arr.length-1;
    }
}

猜你喜欢

转载自blog.csdn.net/hyz792901324/article/details/52576352
今日推荐