You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多列表扩展归并排序实现及Java树形日常活动标签系统开发问询

我来帮你拆解这两个问题,都是开发中很实用的场景,咱们一步步来:

一、多列表的扩展归并排序实现

归并排序原本是针对两个有序列表的合并逻辑,要扩展到多个有序列表,最高效的思路是借助**优先队列(最小堆)**来快速定位所有列表中的当前最小元素,具体实现如下:

核心逻辑

  1. 初始化优先队列,存储每个非空列表的首个元素及其所属列表的迭代器;
  2. 循环从队列中取出最小元素,加入结果集;
  3. 如果该元素所在列表还有后续元素,就将下一个元素加入队列;
  4. 直到队列清空,得到完整的合并有序列表。

Java 代码实现

这里以合并整数有序列表为例,你可以根据业务需求替换元素类型:

import java.util.*;

public class MultiListMergeSort {
    public static <T extends Comparable<T>> List<T> mergeSortedLists(List<List<T>> sortedLists) {
        // 最小堆:按元素自然排序,封装元素和所属列表的迭代器
        PriorityQueue<QueueElement<T>> minHeap = new PriorityQueue<>(Comparator.comparing(QueueElement::getValue));
        
        // 初始化堆:把每个非空列表的第一个元素加入队列
        for (List<T> list : sortedLists) {
            if (!list.isEmpty()) {
                Iterator<T> iterator = list.iterator();
                minHeap.add(new QueueElement<>(iterator.next(), iterator));
            }
        }
        
        List<T> mergedResult = new ArrayList<>();
        while (!minHeap.isEmpty()) {
            QueueElement<T> current = minHeap.poll();
            mergedResult.add(current.getValue());
            
            // 如果当前列表还有下一个元素,继续加入堆
            if (current.getIterator().hasNext()) {
                minHeap.add(new QueueElement<>(current.getIterator().next(), current.getIterator()));
            }
        }
        
        return mergedResult;
    }
    
    // 辅助类:封装元素和迭代器,方便堆排序
    private static class QueueElement<T> {
        private final T value;
        private final Iterator<T> iterator;
        
        public QueueElement(T value, Iterator<T> iterator) {
            this.value = value;
            this.iterator = iterator;
        }
        
        public T getValue() {
            return value;
        }
        
        public Iterator<T> getIterator() {
            return iterator;
        }
    }
    
    // 测试示例
    public static void main(String[] args) {
        List<List<Integer>> lists = Arrays.asList(
            Arrays.asList(1, 4, 7),
            Arrays.asList(2, 5, 8),
            Arrays.asList(3, 6, 9)
        );
        List<Integer> merged = mergeSortedLists(lists);
        System.out.println(merged); // 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]
    }
}

注意事项

  • 若元素未实现Comparable,可以自定义Comparator传入优先队列;
  • 务必处理空列表的情况,避免空指针异常;
  • 时间复杂度为O(N log K)(N是总元素数,K是列表数量),效率优于多次两两合并。
二、Java 树形标签系统(带嵌套引用)实现

针对日常活动记录的树形标签需求,我们可以设计一个Tag类,通过父标签引用和子标签列表实现嵌套结构,完全满足你的需求:

核心类设计

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Tag {
    private String name;
    // 父标签引用(根标签的parent为null)
    private Tag parent;
    // 子标签列表
    private List<Tag> children;
    
    // 构造根标签(无父标签)
    public Tag(String name) {
        this.name = name;
        this.parent = null;
        this.children = new ArrayList<>();
    }
    
    // 构造子标签(私有,通过addChild方法创建,自动维护父子关系)
    private Tag(String name, Tag parent) {
        this.name = name;
        this.parent = parent;
        this.children = new ArrayList<>();
        parent.children.add(this); // 自动加入父标签的子列表
    }
    
    // 对外暴露的添加子标签方法
    public Tag addChild(String childName) {
        return new Tag(childName, this);
    }
    
    // 获取父标签
    public Tag getParent() {
        return parent;
    }
    
    // 获取子标签列表(返回副本,防止外部随意修改)
    public List<Tag> getChildren() {
        return new ArrayList<>(children);
    }
    
    // 获取标签的完整路径(比如 Monetary -> Allowance -> Monthly allowance)
    public String getFullPath() {
        if (parent == null) {
            return name;
        }
        return parent.getFullPath() + " -> " + name;
    }
    
    // 深度优先遍历标签树
    public void traverseDFS() {
        System.out.println(getFullPath());
        for (Tag child : children) {
            child.traverseDFS();
        }
    }
    
    // 递归查找指定名称的标签
    public Tag findTagByName(String targetName) {
        if (name.equals(targetName)) {
            return this;
        }
        for (Tag child : children) {
            Tag found = child.findTagByName(targetName);
            if (found != null) {
                return found;
            }
        }
        return null;
    }
    
    @Override
    public String toString() {
        return name + (children.isEmpty() ? "" : " [" + children.stream().map(Tag::getName).collect(Collectors.joining(", ")) + "]");
    }
    
    public String getName() {
        return name;
    }
}

使用示例

public class TagSystemDemo {
    public static void main(String[] args) {
        // 构建树形标签
        Tag monetary = new Tag("Monetary");
        
        // 添加一级子标签
        Tag allowance = monetary.addChild("Allowance");
        monetary.addChild("Food and drinks");
        monetary.addChild("Rent");
        
        // 给Allowance添加嵌套子标签
        allowance.addChild("Yearly allowance");
        allowance.addChild("Monthly allowance");
        allowance.addChild("Daily allowance");
        
        // 测试深度遍历
        System.out.println("标签树深度优先遍历:");
        monetary.traverseDFS();
        
        // 测试查找标签
        Tag monthlyAllowance = monetary.findTagByName("Monthly allowance");
        if (monthlyAllowance != null) {
            System.out.println("\n找到的标签完整路径:" + monthlyAllowance.getFullPath());
            System.out.println("它的父标签是:" + monthlyAllowance.getParent().getName());
        }
    }
}

关键特性说明

  • 引用关系:子标签通过parent持有父标签引用,父标签通过children持有子标签列表,完美实现嵌套;
  • 封装性:子标签只能通过父标签的addChild方法创建,自动维护父子关系,避免手动操作出错;
  • 实用方法:内置遍历、查找、路径获取等功能,满足日常记录需求;
  • 防循环引用:通过私有构造方法限制子标签创建逻辑,避免出现父子互相引用的死循环。

扩展建议

  • 若需持久化,可添加id字段配合数据库主键;
  • 可增加description字段记录标签说明;
  • 标签数量大时,可缓存常用标签提升查找效率。

内容的提问来源于stack exchange,提问作者157 239n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:48:56