多列表扩展归并排序实现及Java树形日常活动标签系统开发问询
我来帮你拆解这两个问题,都是开发中很实用的场景,咱们一步步来:
一、多列表的扩展归并排序实现
归并排序原本是针对两个有序列表的合并逻辑,要扩展到多个有序列表,最高效的思路是借助**优先队列(最小堆)**来快速定位所有列表中的当前最小元素,具体实现如下:
核心逻辑
- 初始化优先队列,存储每个非空列表的首个元素及其所属列表的迭代器;
- 循环从队列中取出最小元素,加入结果集;
- 如果该元素所在列表还有后续元素,就将下一个元素加入队列;
- 直到队列清空,得到完整的合并有序列表。
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
相关产品推荐
相关产品推荐

