Linux安装软件包时的“依赖关系树”算法(C#)
最近给自己的笔记本装了Ubuntu系统。每次在用 “sudo apt-get install <packages>” 或其他涉及安装软件包命令的时候,总会给出一行提示 “正在分析软件包的依赖关系树”。
本人对这个提示中的“依赖关系树”颇有兴趣。于是决定自己写一个算法来模拟一下这个生成树算法。
1. 用一个xml文件来模拟各个软件包的依赖关系:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <package name="A" id="0"> 3 <package name="B" id="1"> 4 <package name="E" id="4"> 5 <package name="I" id="8"></package> 6 <package name="J" id="9"> 7 <package name="K" id="10"></package> 8 </package> 9 </package> 10 </package> 11 <package name="C" id="2"> 12 <package name="F" id="5"></package> 13 </package> 14 <package name="D" id="3"> 15 <package name="G" id="6"></package> 16 <package name="H" id="7"></package> 17 </package> 18 </package>
View Code
2.生成那棵传说中的依赖关系树:
2.1 定义树节点(TreeNode):
1 public class TreeNode 2 { 3 #region 构造区域 4 5 public TreeNode() 6 { 7 Children = null; 8 Parent = null; 9 Displayed = false; 10 } 11 12 #endregion 13 14 15 #region 属性区域 16 17 /// <summary> 18 /// 节点标识。 19 /// </summary> 20 public string ID { get; set; } 21 22 /// <summary> 23 /// 节点名称。 24 /// </summary> 25 public string Name { get; set; } 26 27 /// <summary> 28 /// 该节点下所有子节点。 29 /// </summary> 30 public List<TreeNode> Children { get; set; } 31 32 /// <summary> 33 /// 该节点父节点。 34 /// </summary> 35 public TreeNode Parent { get; set; } 36 37 /// <summary> 38 /// 节点所处层级。 39 /// </summary> 40 public int Level { get; set; } 41 42 /// <summary> 43 /// 是否已经显示。 44 /// </summary> 45 public bool Displayed { get; set; } 46 47 #endregion 48 49 50 }
View Code
2.2 树的数据结构(Tree):
1 public class Tree 2 { 3 #region 构造方法 4 5 public Tree() 6 { 7 this.Root = null; 8 this.QueueTree = null; 9 } 10 11 #endregion 12 13 #region 属性区域 14 15 /// <summary> 16 /// 根。 17 /// </summary> 18 public TreeNode Root { get; set; } 19 20 /// <summary> 21 /// 队列式树节点链。 22 /// </summary> 23 public Queue<List<TreeNode>> QueueTree { get; set; } 24 25 #endregion 26 27 28 #region 方法区域 29 30 /// <summary> 31 /// 深度遍历显示树。 32 /// </summary> 33 /// <param name="tree"></param> 34 public void DepthDisplayTree() 35 { 36 Display(this.Root, 0); 37 } 38 39 /// <summary> 40 /// 递归显示树节点。(深度遍历) 41 /// </summary> 42 /// <param name="tNode"></param> 43 /// <param name="level"></param> 44 private void Display(TreeNode tNode, int level) 45 { 46 DisplayNode(tNode); 47 if (tNode.Children != null) 48 { 49 foreach (var node in tNode.Children) 50 { 51 Display(node, level + 1); 52 } 53 } 54 } 55 56 /// <summary> 57 /// 递归显示树节点。(广度遍历) 58 /// </summary> 59 /// <param name="tNode"></param> 60 /// <param name="level"></param> 61 private void BreadthDisplayTree(TreeNode tNode) 62 { 63 if (tNode.Parent != null && tNode.Parent.Children != null) 64 { 65 foreach (var node in tNode.Parent.Children) 66 { 67 DisplayNode(node); 68 } 69 } 70 else 71 { 72 DisplayNode(tNode); 73 } 74 75 if (tNode.Children != null) 76 { 77 foreach (var node in tNode.Children) 78 { 79 BreadthDisplayTree(node); 80 } 81 } 82 } 83 84 85 86 /// <summary> 87 /// 广度遍历树。 88 /// </summary> 89 public void BreadDisplay() 90 { 91 BreadthDisplayTree(this.Root); 92 } 93 94 95 96 /// <summary> 97 /// 自下而上广度遍历。 98 /// </summary> 99 public void BreadDisplayDownToUp() 100 { 101 while (QueueTree.Count > 0) 102 { 103 List<TreeNode> list = QueueTree.Dequeue(); 104 105 foreach (TreeNode node in list) 106 { 107 DisplayNode(node); 108 } 109 } 110 } 111 112 113 114 115 /// <summary> 116 /// 显示一个树节点。 117 /// </summary> 118 /// <param name="node"></param> 119 private void DisplayNode(TreeNode node) 120 { 121 if (!node.Displayed) 122 { 123 Console.WriteLine(string.Format("level:{0},Id:{1},Name:{2}", node.Level, node.ID, node.Name)); 124 node.Displayed = true; 125 } 126 } 127 128 129 130 #endregion 131 132 }
View Code
2.3 最主要的生成树算法(递归实现)。
1 public static class ReferTreeGenerator 2 { 3 #region 构造区域 4 5 static ReferTreeGenerator() 6 { 7 } 8 9 #endregion 10 11 #region 字段区域 12 13 static Queue<List<TreeNode>> queueTree = new Queue<List<TreeNode>>(); 14 15 #endregion 16 17 #region 方法区域 18 19 /// <summary> 20 /// XmlNode 转化为 TreeNode。 21 /// </summary> 22 /// <param name="node"></param> 23 /// <returns></returns> 24 private static TreeNode XmlNodeToTreeNode(XmlNode node) 25 { 26 TreeNode rstNode = new TreeNode(); 27 rstNode.ID = node.Attributes["id"].Value; 28 rstNode.Name = node.Attributes["name"].Value; 29 return rstNode; 30 } 31 32 /// <summary> 33 /// 获取数据目录。 34 /// </summary> 35 /// <returns></returns> 36 private static string GetDataPath() 37 { 38 string currPath = Directory.GetCurrentDirectory() 39 , result = string.Empty; 40 41 string[] paths = currPath.Split('\\'); 42 43 for (int i = 0; i < paths.Length - 2; i++) 44 { 45 result += paths[i] + "\\"; 46 } 47 result += "ReferenceTree\\Source\\Data.xml"; 48 return result; 49 } 50 51 /// <summary> 52 /// 递归生成树。 53 /// </summary> 54 /// <param name="xml"></param> 55 /// <param name="level"></param> 56 /// <param name="tree"></param> 57 private static void GenTree(XmlNode xml, int level, TreeNode tree) 58 { 59 List<TreeNode> list = new List<TreeNode>(); 60 tree.Children = list; 61 62 foreach (XmlNode item in xml.ChildNodes) 63 { 64 TreeNode treeNode = XmlNodeToTreeNode(item); 65 treeNode.Parent = tree; 66 treeNode.Level = level; 67 68 tree.Children.Add(treeNode); 69 70 if (item.HasChildNodes) GenTree(item, level + 1, treeNode); 71 } 72 queueTree.Enqueue(list); 73 } 74 75 /// <summary> 76 /// 根据xml生成Tree。 77 /// </summary> 78 /// <returns></returns> 79 public static Tree GenTreeFromXml() 80 { 81 XmlDocument doc = new XmlDocument(); 82 doc.Load(GetDataPath()); 83 84 //初始化递归 85 XmlNode xmlRoot = doc.DocumentElement; 86 TreeNode treeRoot = XmlNodeToTreeNode(xmlRoot); 87 treeRoot.Parent = null; 88 treeRoot.Level = 0; 89 90 GenTree(xmlRoot, 1, treeRoot); 91 92 Tree tree = new Tree(); 93 tree.Root = treeRoot; 94 return tree; 95 } 96 97 /// <summary> 98 /// 生成队列式Tree。 99 /// </summary> 100 /// <returns></returns> 101 public static Tree GenerateQueuedTree() 102 { 103 XmlDocument doc = new XmlDocument(); 104 Tree tree = new Tree(); 105 InitialTree(doc, tree); 106 GenTree(doc.DocumentElement, 1, tree.Root); 107 108 queueTree.Enqueue(new List<TreeNode>() { tree.Root }); 109 return tree; 110 } 111 112 /// <summary> 113 /// 初始化树。 114 /// </summary> 115 /// <param name="doc"></param> 116 /// <param name="tree"></param> 117 private static void InitialTree(XmlDocument doc, Tree tree) 118 { 119 doc.Load(GetDataPath()); 120 121 //初始化递归 122 XmlNode xmlRoot = doc.DocumentElement; 123 TreeNode treeRoot = XmlNodeToTreeNode(xmlRoot); 124 treeRoot.Parent = null; 125 treeRoot.Level = 0; 126 127 tree.QueueTree = queueTree; 128 tree.Root = treeRoot; 129 } 130 #endregion 131 132 }
View Code
3.调用
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Tree tree = ReferTreeGenerator.GenerateQueuedTree(); 6 7 Console.WriteLine("Queued Tree:"); 8 tree.BreadDisplayDownToUp(); 9 10 Console.ReadLine(); 11 } 12 }
View Code
4.结果:
总结:
按照这个顺序安装package,就不会有引用的错误啦。
由于时间仓促,算法肯定有些不尽人意的地方。若有意见,还请不吝赐教。:)
转载于:https://www.cnblogs.com/devindong/p/3177886.html
Linux安装软件包时的“依赖关系树”算法(C#)相关推荐
- Linux安装软件时缺少依赖包的简单较完美解决方法!
Linux安装软件时缺少依赖包的简单较完美解决方法! 参考文章: (1)Linux安装软件时缺少依赖包的简单较完美解决方法! (2)https://www.cnblogs.com/xiaommvik/ ...
- 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是 因为系统
解决办法一 sudo apt-get update sudo apt-get upgrade 一般这样就ok 了 还不行换个源 ,也就是说当前这个源没有这个包,换个源,推荐华为源,是我目前试过最快的, ...
- dpkg: 处理软件包 nginx (--configure)时出错: 依赖关系问题 - 仍未被配置
wangyetao@wangyetao-Lenovo-G510:~$ sudo apt install nginx 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状 ...
- 【错误记录】Ubuntu 安装软件报错 ( 下列软件包有未满足的依赖关系:E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。 )
文章目录 一.报错信息 二.解决方案 一.报错信息 执行 sudo apt-get install git 命令 , 安装 git 软件 , 报如下错误 : root@octopus:~/ijkpla ...
- Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题)
Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题) 参考文章: (1)Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题) (2)https://www.cnblogs. ...
- Linux源码安装软件包时--prefix的配置建议
我们知道,使用源码安装软件包时通常会提供一个config或configure脚本对安装进行一些必要的配置,其中最为常见的是–prefix选项,它用于指定软件安装的父级目录,也就是将软件安装在哪个文件夹 ...
- ubuntu中手动编译源码安装Xorg-server过程中依赖关系的解决
ubuntu中手动编译源码安装Xorg-server过程中依赖关系的解决 在linux系统中手动编译源码安装软件包的过程是非常痛苦的,然而这一个多星期以来我是强忍住脾气体验了一把,虽然面对慢的令人发指 ...
- linux安装软件包遇到的一些问题,无法成功安装软件
在玩linux系统时,我们常常要通过sudu apt-get install 软件命令来安装很多软件,但有时候事情并没有那么顺利,不能想安装哪个就安装哪个软件,总是会出现各种各样的问题,在我遇到的问题 ...
- 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系
使用 sudo apt-get install 安装软件时, 出现错误 "无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系". 错误的主要原因是,系统中 ...
- 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。ubu
有一些软件包无法被安装.如果您用的是 unstable 发行版,这也许是 因为系统无法达到您要求的状态造成的.该版本中可能会有一些您需要的软件 包尚未被创建或是它们已被从新到(Incoming)目录移 ...
最新文章
- 合理的使用纯函数式编程
- 【知识强化】第一章 操作系统概述 1.1 操作系统的基本概念
- form-validation-engine中的正则表达式
- [转]HTTP/3 未来可期?
- python库文件安装_python安装库包出现问题
- 抗滑桩初始弹性系数计算_抗滑桩配筋计算.docx
- Go语言的big包实现大整数运算
- libiconv android,iconv库 android ndk可运行
- android:scaleType=centerCrop
- SpringBoot及SpringCloud版本管理(Gradle版本)
- 亚马逊结算一览(C#项目)
- BOS EAS 实体增加字段,关联核算项目
- animation 详细讲解
- 沧海的孤塔-chimera
- 同是匿名社交,国内外“秘密”大不同
- 超全整理100个 Pandas 函数,建议收藏!
- Ubuntu16 wine安装迅雷
- linux中seliunux配置文件,SELinux 入门简介
- 关于android webview 端调原生app 的支付宝接口实现 还有BeeCloud(秒支付) 的接入使用
- 【SLAM】LIO-SAM解析——后端优化mapOptimization(5)
热门文章
- 【位运算经典应用】 N皇后问题
- Activiti流程定义部署、删除
- JSP 2.2规范 对jsp:useBean的解释
- java生成字符_java中随机生成字符串的方法(三种)
- ElasticSearch入门详解
- 分页缓冲池内存过高_揭秘:为什么新买的8G内存却显示4G可用,是系统出错还是被人坑了?...
- linux启动器编辑,linux下建立启动器
- php 配置文件类,PHP配置文件类
- 点线面的特点_黑白装饰画——点线面 设计入门必备
- 用户信息填写web代码_zabbix监控系列之监控项(8、web监控)