目录删除_200分_A/B卷复用_树/递归

目录删除

题目描述:

  某文件系统中有 N 个目录,每个目录都有一个独一无二的 ID。
  每个目录只有一个父目录,但每个父目录下可以有零个或者多个子目录,目录结构呈树状结构。
  假设,根目录的 ID 为 0,且根目录没有父目录,其他所有目录的 ID 用唯一的正整数表示,并统一编号。
  现给定目录 ID 和其父目录 ID 的对应父子关系表[子目录 ID,父目录 ID],以及一个待删除的目录 ID,
  请计算并返回一个 ID 序列,表示因为删除指定目录后剩下的所有目录,返回的ID序列以递增序输出。
  注意:
    1、被删除的目录或文件编号一定在输入的 ID 序列中;
    2、当一个目录删除时,它所有的子目录都会被删除。

输入输出描述:

输入描述:

  输入的第一行为父子关系表的长度 m;
  接下来的 m 行为 m 个父子关系对;
  最后一行为待删除的 ID。
  序列中的元素以空格分割,参见样例。

输出描述:

  输出一个序列,表示因为删除指定目录后,剩余的目录 ID。

示例1:

输入:
	5
	8 6
	10 8
	6 0
	20 8
	2 6
	8
输出:
	2 6

解题思路:

如图,根据示例创建出来的树形结构,删除节点8之后,8、10、20这三个节点都被删除掉。
已经给出了节点之间的父子关系,可以使用一个Map来记录创建了哪些接地那,可以快速的建立出树来。
删除的时候,通过递归(即后序遍历)的方式进行删除
在这里插入图片描述

代码:

public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	int m = Integer.parseInt(scanner.nextLine());
	Map<Integer, Node> map = new TreeMap<>();

	// 根据输入的节点关系,创建树状节点
	for (int i = 0; i < m; i++) {
		String[] split = scanner.nextLine().split(" ");
		int childId = Integer.parseInt(split[0]);
		int parentId = Integer.parseInt(split[1]);

		// 如果父节点还没被创建
		if (!map.containsKey(parentId)) {
			Node parent = new Node();
			parent.id = parentId;
			parent.children = new ArrayList<>();
			// 记录已经创建的节点
			map.put(parentId, parent);
		}
		// 如果子节点还没被创建
		if (!map.containsKey(childId)) {
			Node cur = new Node();
			cur.id = childId;
			cur.children = new ArrayList<>();
			// 记录已经创建的节点
			map.put(childId, cur);
		}

		// 建立父子关系
		map.get(parentId).children.add(map.get(childId));
	}

	// 获取要删除的文件 Id
	int deleteId = Integer.parseInt(scanner.nextLine());
	if (deleteId == 0) {
		// 删除的是根节点,所有目录都删除,输出空
		System.out.println();
		return;
	}
	
	// 删除目录及其子目录
	deleteFile(deleteId, map);

	int index = 0;
	for (Integer integer : map.keySet()) {
		// 根节点 0 没有要求输出出来
		if (integer != 0) {
			if (index++ > 0) {
				System.out.print(" ");
			}
			System.out.print(integer);
		}
	}
}

// 删除目录及其子目录
private static void deleteFile(int deleteId, Map<Integer, Node> map) {
	if (!map.containsKey(deleteId)) {
		return;
	}

	// 递归删除子节点
	for (Node child : map.get(deleteId).children) {
		deleteFile(child.id, map);
	}
	// 删除完子节点后,删除当前节点
	map.remove(deleteId);
}

// 节点类
static class Node {
	// 文件目录id
	int id;
	// 子文件
	List<Node> children;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值