How to convert a hierarchy list to a binary tree

I am working on multi-level marketing (binary) that looks like this:

(but the binary tree does not have to be perfect. node can have 0-2 children)

enter image description here

My problem is the data that I get from the database is a flat list. enter image description here enter image description here

Please note that I am using hierarchyid (sql server 2014)

Basically, a TextNode column TextNode like a palette.

each dash / represents a level .

If I have TextNode /1/ as root. then each node that starts with /1/ belongs to this root, which are /1/ , /1/1/ and /1/1/1/ 1/1/1 /1/1/1/ (the root of the node is turned on, which will be level 0)

I tried the accepted answer in this question, but it does not work.

How to convert a flat list to a binary tree so that I can easily navigate and display it on the screen?

I use C #, ASP MVC 5, SQL Server 2014, if that matters.

+4
source share
1 answer

Here is a very simple implementation (assuming the nodes are in the correct order) that can be expanded in several ways.

 public interface IRow<out T> { string TextNode { get; } T Value { get; } } public class TreeNode<T> { private struct NodeDescriptor { public int Level { get; } public int ParentIndex { get; } public NodeDescriptor(IRow<T> row) { var split = row.TextNode.Split(new [] {"/"}, StringSplitOptions.RemoveEmptyEntries); Level = split.Length; ParentIndex = split.Length > 1 ? int.Parse(split[split.Length - 2]) - 1 : 0; } } public T Value { get; } public List<TreeNode<T>> Descendants { get; } private TreeNode(T value) { Value = value; Descendants = new List<TreeNode<T>>(); } public static TreeNode<T> Parse(IReadOnlyList<IRow<T>> rows) { if (rows.Count == 0) return null; var result = new TreeNode<T>(rows[0].Value); FillParents(new[] {result}, rows, 1, 1); return result; } private static void FillParents(IList<TreeNode<T>> parents, IReadOnlyList<IRow<T>> rows, int index, int currentLevel) { var result = new List<TreeNode<T>>(); for (int i = index; i < rows.Count; i++) { var descriptor = new NodeDescriptor(rows[i]); if (descriptor.Level != currentLevel) { FillParents(result, rows, i, descriptor.Level); return; } var treeNode = new TreeNode<T>(rows[i].Value); parents[descriptor.ParentIndex].Descendants.Add(treeNode); result.Add(treeNode); } } } 

Sample Usage:

 public class Row : IRow<string> { public string TextNode { get; } public string Value { get; } public Row(string textNode, string userName) { TextNode = textNode; Value = userName; } } class Program { static void Main(string[] args) { IRow<string>[] rows = { new Row("/", "Ahmed"), new Row("/1/", "Saeed"), new Row("/2/", "Amjid"), new Row("/1/1/", "Noura"), new Row("/2/1/", "Noura01"), new Row("/2/2/", "Reem01"), new Row("/1/1/1", "Under_noura") }; var tree = TreeNode<string>.Parse(rows); PrintTree(tree); } private static void PrintTree<T>(TreeNode<T> tree, int level = 0) { string prefix = new string('-', level*2); Console.WriteLine("{0}{1}", prefix, tree.Value); foreach (var node in tree.Descendants) { PrintTree(node, level + 1); } } } 
0
source

All Articles