• 归并排序处理复杂对象例子


    对象TmpObject 包含了一个 int类型的变量,有一个List<TmpObject> 数组,如何根据这个int变量,进行归并排序?

      1 import java.util.ArrayList;
      2 import java.util.List;
      3 
      4 /**
      5  * 归并排序(递归)
      6  */
      7 public class Merge {
      8     public static void main(String[] args) {
      9         List<TmpObject> list = new ArrayList<>();
     10         list.add(new TmpObject(6));
     11         list.add(new TmpObject(5));
     12         list.add(new TmpObject(3));
     13         list.add(new TmpObject(8));
     14         list.add(new TmpObject(1));
     15         list.add(new TmpObject(7));
     16         list.add(new TmpObject(2));
     17         list.add(new TmpObject(9));
     18         list.add(new TmpObject(5));
     19 
     20         System.out.println("归并前输出:");
     21         for (TmpObject tmp : list) {
     22             System.out.print(tmp.getNum() +" ");
     23         }
     24 
     25         segment(list, 0, list.size() - 1);
     26 
     27         System.out.println("
    归并后输出:");
     28         for (TmpObject tmp : list) {
     29             System.out.print(tmp.getNum() +" ");
     30         }
     31     }
     32 
     33     /**
     34      * 递归切分待排
     35      *
     36      * @param list  待切分数组
     37      * @param left  待切分最后第一个元素的索引
     38      * @param right 待切分数组最后一个元素的索引
     39      */
     40     private static void segment(List<TmpObject> list, int left, int right) {
     41         if (left < right) {
     42             // 找出中间索引
     43             int center = (left + right) / 2;
     44             // 对左边数组进行递归
     45             segment(list, left, center);
     46             // 对右边数组进行递归
     47             segment(list, center + 1, right);
     48             // 合并
     49             merge(list, left, center, right);
     50         }
     51     }
     52 
     53     /**
     54      * 两两归并排好序的数组(2路归并)
     55      *
     56      * @param list   带排序数组对象
     57      * @param left   左边数组的第一个索引
     58      * @param center 左数组的最后一个索引,center + 1右数组的第一个索引
     59      * @param right  右数组的最后一个索引
     60      */
     61     private static void merge(List<TmpObject> list, int left, int center, int right) {
     62         List<TmpObject> tmpArray = new ArrayList<TmpObject>(right - left + 1);
     63         int leftIndex = left;   //左数组第一个元素的索引
     64         int rightIndex = center + 1;   //右数组第一个元素索引
     65 
     66         // 把较小的数先移到新数组中
     67         while (leftIndex <= center && rightIndex <= right) {
     68             if (list.get(leftIndex).getNum() <= list.get(rightIndex).getNum()) {
     69                 tmpArray.add(list.get(leftIndex++));
     70             } else {
     71                 tmpArray.add(list.get(rightIndex++));
     72             }
     73         }
     74 
     75         //把左边剩余的数移入数组
     76         while (leftIndex <= center) {
     77             tmpArray.add(list.get(leftIndex++));
     78         }
     79 
     80         // 把右边边剩余的数移入数组
     81         while (rightIndex <= right) {
     82             tmpArray.add(list.get(rightIndex++));
     83         }
     84 
     85         // 把新数组中的数覆盖nums数组
     86         for (int i = 0; i < tmpArray.size(); i++) {
     87             list.set(left + i, tmpArray.get(i));
     88         }
     89     }
     90 }
     91 
     92 class TmpObject {
     93     private int num;
     94 
     95     TmpObject(int num) {
     96         this.num = num;
     97     }
     98 
     99     int getNum() {
    100         return num;
    101     }
    102 
    103     void setNum(int num) {
    104         this.num = num;
    105     }
    106 }

     输出结果为:

    归并前输出:
    6 5 3 8 1 7 2 9 5
    归并后输出:
    1 2 3 5 5 6 7 8 9

    可以使用Comparator 比较器来直接比较list,而且它的排序方法是TimSort 算法:

    //java8 中自定义Comparator 可以使用lambda 表达式
    private static void sortList(List<TmpObject> list) {
        Comparator comp = (o1, o2) -> {
            TmpObject tmpFirst = (TmpObject) o1;
            TmpObject tmpSecond = (TmpObject) o2;
            return tmpFirst.getNum() - tmpSecond.getNum();
        };
        list.sort(comp);
    }
  • 相关阅读:
    WCF系列(五) 也谈序列化(下)
    优秀程序员的十个习惯
    WCF系列(九) WCF安全系列(四) WSHttpBinding绑定之Transport安全模式
    TCP/IP 协议简单分析
    技巧:在Silverlight应用程序中进行数据验证
    WCF系列(三) WCF配置文件注释
    [转]ASP.NET(C#)常用代码30例
    服务器端 在iframe中控制父窗体div并调用父窗体Button
    GridView的模版列中加入按钮,触发按钮事件后,如何获取该行的某个值?
    通用分页 模块
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/merge-object.html
Copyright © 2020-2023  润新知