admin
2024-09-20 8b7b39172ee548ff303dbd73816cb7c1071f7887
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace CommonHelper.SNode
{
    public class MultiTree
    {
        //private Stack<MTreeNode> t_stack;
        private Queue<MTreeNode> queue_t = new Queue<MTreeNode>();
 
 
        /// <summary>  
        /// 深度优先遍历查找  
        /// </summary>  
        /// <param name="name">查找内容</param>  
        /// <param name="head">当前节点(从首节点开始)</param>  
        /// <returns>目标节点</returns>  
        private static MTreeNode search_node_r(string name, MTreeNode head)
        {
            MTreeNode temp = null;
            if (head != null)
            {
                if (name.Equals(head.Name))
                {
                    temp = head; //如果名字匹配  
                }
                else //如果不匹配,则查找其子节点  
                {
                    for (int i = 0; i < head.NChildren && temp == null; i++)
                    {
                        temp = search_node_r(name, head.Children[i]);
                    }
                }
            }
            return temp;
        }
 
        /// <summary>  
        /// 从文件中读取多叉树数据,并建立多叉树  
        /// </summary>  
        /// <param name="head">多叉树根节点</param>  
        /// <param name="filePath">文件路径</param>  
        public static void read_file(ref MTreeNode head, string filePath)
        {
            MTreeNode temp = null;
            int n;
            string name, child;
            using (StreamReader sr = new StreamReader(filePath))
            {
                //一行行读取直至为NULL  
                string strLine = string.Empty;
                while ((strLine = sr.ReadLine()) != null)
                {
                    string[] strings = strLine.Split(' ');
                    name = strings[0];
                    n = int.Parse(strings[1]);
                    if (head == null) //若为空  
                    {
                        //让temp和head引用同一块内存空间  
                        temp = head = new MTreeNode(); //生成一个新节点  
                        temp.Name = name; //赋名  
                    }
                    else
                    {
                        temp = search_node_r(name, head);
                        //这里默认数据文件是正确的,一定可以找到与name匹配的节点  
                        //如果不匹配,那么应该忽略本行数据  
                    }
                    //找到节点后,对子节点进行处理  
                    temp.NChildren = n;
                    for (int i = 0; i < n; i++)
                    {
                        child = strings[i + 2];
                        temp.Children.Add(new MTreeNode());
                        temp.Children[i].Name = child;
                    }
                }
            }
 
        }
 
        /// <summary>  
        /// 实现函数1  
        /// 将多叉树中的节点,按照深度进行输出  
        /// 实质上实现的是层次优先遍历  
        /// </summary>  
        /// <param name="head">首节点</param>  
        private static void f1(MTreeNode head)
        {
            MTreeNode tMTreeNode;
            Queue<MTreeNode> queue = new Queue<MTreeNode>(100); //将队列初始化大小为100  
            Stack<MTreeNode> stack = new Stack<MTreeNode>(100); //将栈初始化大小为100  
            head.Level = 0; //根节点的深度为0  
 
            //将根节点入队列  
            queue.Enqueue(head);
 
            //对多叉树中的节点的深度值level进行赋值  
            //采用层次优先遍历方法,借助于队列  
            while (queue.Count != 0) //如果队列q不为空  
            {
                tMTreeNode = queue.Dequeue(); //出队列  
                for (int i = 0; i < tMTreeNode.NChildren; i++)
                {
                    tMTreeNode.Children[i].Level = tMTreeNode.Level + 1; //对子节点深度进行赋值:父节点深度加1  
                    queue.Enqueue(tMTreeNode.Children[i]); //将子节点入队列  
                }
                stack.Push(tMTreeNode); //将p入栈  
            }
 
            while (stack.Count != 0) //不为空  
            {
                tMTreeNode = stack.Pop(); //弹栈  
                System.Diagnostics.Debug.WriteLine("   {0} {1}", tMTreeNode.Level, tMTreeNode.Name);
            }
        }
 
        /// <summary>  
        /// 实现函数2  
        /// 找到从根节点到叶子节点路径上节点名字字母个数最大的路径  
        /// 实质上实现的是深度优先遍历  
        /// </summary>  
        /// <param name="head">首节点</param>  
        /// <param name="str">临时字符串</param>  
        /// <param name="strBest">从根节点到叶子节点路径上节点名字字母个数最大的路径</param>  
        /// <param name="level">当前深度</param>  
        private static void f2(MTreeNode head, string str, ref string strBest, int level)
        {
            if (head == null) return;
            var tmp = str + head.Name;
 
            if (head.NChildren == 0)
            {
                if (strBest == null || tmp.Length > strBest.Length)
                {
                    strBest = tmp;
                }
            }
            for (var i = 0; i < head.NChildren; i++)
            {
                f2(head.Children[i], tmp, ref strBest, level + 1);
            }
        }
 
        private void free_tree_r(MTreeNode head)
        {
            if (head == null)
                return;
            head = null;
        }
 
        //MTreeNode head = null;
        //string strBest = null;
        //read_file(ref head, "TextFile1.txt");
        //System.Diagnostics.Debug.WriteLine("f1:");  
        //f1(head);
        //f2(head, "", ref strBest, 0);
        //System.Diagnostics.Debug.WriteLine("f2:\n   {0}", strBest);  
        //Console.ReadKey();  
 
    }
}