将列表按照父子关系深度优先遍历顺序排序

问题

在项目中 我们经常需要将一个有父子关系的列表按照树的深度优先遍历的方式排序。所以写了一个通用的排序算法。

源码

github 地址: CollectionsOpt.java。更多分享参见 https://ndxt.github.io。 

 public interface ParentChild<T> {
        boolean parentAndChild(T p, T c);
    }

public static <T> void sortAsTree(List<T> list, ParentChild<? super T> c) {
        int n=list.size();
        if(n<2)
            return ;
        //sorted 已经排序好的数量
        int sortedInd = 0;
        int [] parentInds = new int [n];
        while(sortedInd < n-1 ){
            // 找到所有的根节点
            int parentInd = -1;
            for(int i= sortedInd;i<n;i++){
                boolean isParent = true;
                for(int j=sortedInd;j<n;j++){
                    if(i != j && c.parentAndChild(list.get(j),list.get(i))){
                        isParent = false;
                        break;
                    }
                }
                if(isParent){
                    parentInd = i;
                    break;
                }
            }
            if(parentInd == -1)
                break;

            moveListItem(list,parentInd,sortedInd);
            parentInds[0]=sortedInd;
            sortedInd ++;
            int pathDeep=1;
            while(pathDeep>0){
                int newInsert = 0;
                for(int i=sortedInd;i<n;i++){
                    if(c.parentAndChild(list.get(parentInds[pathDeep-1]),list.get(i))){
                        moveListItem(list,i,sortedInd);
                        parentInds[pathDeep]=sortedInd;
                        pathDeep ++;
                        sortedInd ++;
                        newInsert ++;
                    }
                }
                if(newInsert==0){
                    pathDeep--;
                }
            }
            // 查找根节点的所有子元素
            //sortedInd = sortAsTreePiece(list,c,sortedInd);
        }
    }

测试


    public static void main(String[] args) {
        List<Integer> nodeList = new ArrayList<Integer>();
        nodeList.add(223);
        nodeList.add(222);
        nodeList.add(221);
        nodeList.add(22);
        nodeList.add(123);
        nodeList.add(121);
        nodeList.add(11);
        nodeList.add(12);
        nodeList.add(21);
        nodeList.add(2);
        nodeList.add(1);

        CollectionsOpt.sortAsTree(nodeList,(p,c)-> p == c / 10);
        System.out.println(nodeList);
    }

结果

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值