“擂台比武式”的归并算法

我怕爱的太早我们不能终老 提交于 2020-03-05 05:39:03

一. 关于“擂台比武”

假设现在有一堆人要进行擂台比武,他们的战斗力如下:
[5, 1, 6, 3, 4, 2, 8]
数字越小代表战斗力越强

现在采用抽签模式,两两对决,胜者进入下一轮(如果奇数,单独人员可直接晋级),情况如下:
在这里插入图片描述

那么,如何把所有人的战斗力排名算出来呢?
在这里插入图片描述

二. 归并算法

如同擂台比武,先拆分成分各组,直到细分为单个,开始比较后合并

注意点:

  1. 拆分的时候要注意奇偶数的问题
  2. 合并的时候要注意比较排序,当一个数组排序完成,另外一个要把剩余的全部补充

三. 代码示例

/**
 * @author yanghao
 * @version MergeTest.java, v 0.1 2020-03-02 15:10
 */
public class MergeTest {

    public static void main(String[] args){
        Integer[] data = {5, 1, 6, 3, 4, 2, 8};

        data = sort(data);

        for(int i = 0;i < data.length; i ++){
            System.out.print(data[i] + " = ");
        }

    }

    private static Integer[] sort(Integer[] data){
        int length = data.length;
        if(length == 0){
            return new Integer[0];
        }

        //分割
        int mid = length%2 == 1 ? (length - 1)/2 : length/2 - 1;
        Integer[] dataLeft = split(data, 0, mid);
        Integer[] dataRight = split(data, mid + 1, length - 1);

        //判断是否要继续分割
        if(dataLeft.length > 1){
            dataLeft = sort(dataLeft);
        }

        if(dataRight.length > 1){
            dataRight = sort(dataRight);
        }

        //排序后合并
        return merge(dataLeft, dataRight);

    }

    /**
     * 拆分数组
     * @param data
     * @param start
     * @param end
     * @return
     */
    private static Integer[] split(Integer[] data, int start, int end) {
        Integer[] temp = new Integer[end - start + 1];
        for(int i = 0;i <= end - start; i ++){
            temp[i] = data[start + i];
        }

        return temp;
    }

    /**
     * 合并数组
     * @param dataLeft
     * @param dataRight
     * @return
     */
    private static Integer[] merge(Integer[] dataLeft, Integer[] dataRight) {
        Integer[] data = new Integer[dataLeft.length + dataRight.length];

        int i = 0,j = 0,k = 0;

        while (i < dataLeft.length && j < dataRight.length){
            if(dataLeft[i] <= dataRight[j]){
                data[k] = dataLeft[i];
                i ++;
            }else{
                data[k] = dataRight[j];
                j ++;
            }

            k ++;
        }

        //如果左边数组没有取完
        while (i < dataLeft.length){
            data[k] = dataLeft[i];
            i ++;
            k ++;
        }

        //如果右边数组没有取完
        while (j < dataRight.length){
            data[k] = dataRight[j];
            j ++;
            k ++;
        }

        return data;
    }

}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!