最近给自己的笔记本装了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#)相关推荐

  1. Linux安装软件时缺少依赖包的简单较完美解决方法!

    Linux安装软件时缺少依赖包的简单较完美解决方法! 参考文章: (1)Linux安装软件时缺少依赖包的简单较完美解决方法! (2)https://www.cnblogs.com/xiaommvik/ ...

  2. 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是 因为系统

    解决办法一 sudo apt-get update sudo apt-get upgrade 一般这样就ok 了 还不行换个源 ,也就是说当前这个源没有这个包,换个源,推荐华为源,是我目前试过最快的, ...

  3. dpkg: 处理软件包 nginx (--configure)时出错: 依赖关系问题 - 仍未被配置

    wangyetao@wangyetao-Lenovo-G510:~$ sudo apt install nginx 正在读取软件包列表... 完成 正在分析软件包的依赖关系树        正在读取状 ...

  4. 【错误记录】Ubuntu 安装软件报错 ( 下列软件包有未满足的依赖关系:E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。 )

    文章目录 一.报错信息 二.解决方案 一.报错信息 执行 sudo apt-get install git 命令 , 安装 git 软件 , 报如下错误 : root@octopus:~/ijkpla ...

  5. Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题)

    Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题) 参考文章: (1)Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题) (2)https://www.cnblogs. ...

  6. Linux源码安装软件包时--prefix的配置建议

    我们知道,使用源码安装软件包时通常会提供一个config或configure脚本对安装进行一些必要的配置,其中最为常见的是–prefix选项,它用于指定软件安装的父级目录,也就是将软件安装在哪个文件夹 ...

  7. ubuntu中手动编译源码安装Xorg-server过程中依赖关系的解决

    ubuntu中手动编译源码安装Xorg-server过程中依赖关系的解决 在linux系统中手动编译源码安装软件包的过程是非常痛苦的,然而这一个多星期以来我是强忍住脾气体验了一把,虽然面对慢的令人发指 ...

  8. linux安装软件包遇到的一些问题,无法成功安装软件

    在玩linux系统时,我们常常要通过sudu apt-get install 软件命令来安装很多软件,但有时候事情并没有那么顺利,不能想安装哪个就安装哪个软件,总是会出现各种各样的问题,在我遇到的问题 ...

  9. 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系

    使用 sudo apt-get install 安装软件时, 出现错误 "无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系". 错误的主要原因是,系统中 ...

  10. 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。ubu

    有一些软件包无法被安装.如果您用的是 unstable 发行版,这也许是 因为系统无法达到您要求的状态造成的.该版本中可能会有一些您需要的软件 包尚未被创建或是它们已被从新到(Incoming)目录移 ...

最新文章

  1. 合理的使用纯函数式编程
  2. 【知识强化】第一章 操作系统概述 1.1 操作系统的基本概念
  3. form-validation-engine中的正则表达式
  4. [转]HTTP/3 未来可期?
  5. python库文件安装_python安装库包出现问题
  6. 抗滑桩初始弹性系数计算_抗滑桩配筋计算.docx
  7. Go语言的big包实现大整数运算
  8. libiconv android,iconv库 android ndk可运行
  9. android:scaleType=centerCrop
  10. SpringBoot及SpringCloud版本管理(Gradle版本)
  11. 亚马逊结算一览(C#项目)
  12. BOS EAS 实体增加字段,关联核算项目
  13. animation 详细讲解
  14. 沧海的孤塔-chimera
  15. 同是匿名社交,国内外“秘密”大不同
  16. 超全整理100个 Pandas 函数,建议收藏!
  17. Ubuntu16 wine安装迅雷
  18. linux中seliunux配置文件,SELinux 入门简介
  19. 关于android webview 端调原生app 的支付宝接口实现 还有BeeCloud(秒支付) 的接入使用
  20. 【SLAM】LIO-SAM解析——后端优化mapOptimization(5)

热门文章

  1. 【位运算经典应用】 N皇后问题
  2. Activiti流程定义部署、删除
  3. JSP 2.2规范 对jsp:useBean的解释
  4. java生成字符_java中随机生成字符串的方法(三种)
  5. ElasticSearch入门详解
  6. 分页缓冲池内存过高_揭秘:为什么新买的8G内存却显示4G可用,是系统出错还是被人坑了?...
  7. linux启动器编辑,linux下建立启动器
  8. php 配置文件类,PHP配置文件类
  9. 点线面的特点_黑白装饰画——点线面 设计入门必备
  10. 用户信息填写web代码_zabbix监控系列之监控项(8、web监控)