I have structure as below
{
"Start": "CDG",
"AirportsRoutes":
{
"BKK" : ["SIN", "DXB", "CDG", "SFO"],
"CDG" : ["LHR", "SIN"],
"JFK" : ["CDG", "DXB"],
"JNB" : ["SIN"],
"SIN" : ["SFO", "BKK"],
"SFO" : ["JFK", "BKK", "LHR"],
"LHR" : ["CDG", "JFK", "DXB"],
"YYZ" : ["SFO", "JFK"],
"DXB" : ["JNB", "SIN", "BKK"]
}
}
I created dictionary for AirportsRoutes as Dictionary<string, List<string>>.
I would like to build tree of data from this dictionary by using value to be next node for example if use "CDG" for root node.
Each leaf node will be stop if found the same key of their parent node.
CDG->LHR->CDG
->LHR->JFK->CDG
->LHR->JFK->DXB->JNB->SIN->SFO->JFK
->LHR->JFK->DXB->JNB->SIN->SFO->BKK
->LHR->JFK->DXB->JNB->SIN->SFO->LHR
->LHR->JFK->DXB->JNB->SIN->BKK...
->LHR->JFK->DXB->SIN->SFO...
->LHR->JFK->DXB->SIN->BKK..
->LHR->JFK->DXB->BKK..
->LHR->DXB..
Does everyone know how to make it or do I need to change Dictionary to something else ?
This little console app does what you want:
public class Program
{
public class TreeNode<T>
{
public List<TreeNode<T>> children = new List<TreeNode<T>>();
public T thisItem;
public TreeNode<T> parent;
}
public static void Main(string[] args)
{
var dict = new Dictionary<string, List<string>>
{
{"BKK", new List<string>{"SIN", "DXB", "CDG", "SFO"}},
{"CDG" , new List<string>{"LHR", "SIN"}},
{"JFK" , new List<string>{"CDG", "DXB"}},
{"JNB" , new List<string>{"SIN"}},
{"SIN" , new List<string>{"SFO", "BKK"}},
{"SFO" , new List<string>{"JFK", "BKK", "LHR"}},
{"LHR" , new List<string>{"CDG", "JFK", "DXB"}},
{"YYZ" , new List<string>{"SFO", "JFK"}},
{"DXB", new List<string> {"JNB", "SIN", "BKK"}}
};
var tree = BuildTree(dict, "CDG");
}
public static TreeNode<T> BuildTree<T>(Dictionary<T, List<T>> dictionary, T root)
{
var newTree = new TreeNode<T>
{
thisItem = root,
};
newTree.children = GetChildNodes(dictionary, newTree);
return newTree;
}
public static List<TreeNode<T>> GetChildNodes<T>(Dictionary<T, List<T>> dictionary, TreeNode<T> parent)
{
var nodeList = new List<TreeNode<T>>();
if (dictionary.ContainsKey(parent.thisItem))
{
foreach (var item in dictionary[parent.thisItem])
{
var nodeToAdd = new TreeNode<T>
{
thisItem = item,
parent = parent,
};
if (!ContainedInParent(parent, item))
{
nodeToAdd.children = GetChildNodes(dictionary, nodeToAdd);
}
// output leaf node for debugging!
if (nodeToAdd.children.Count == 0)
{
Console.WriteLine(NodeString(nodeToAdd));
}
nodeList.Add(nodeToAdd);
}
}
return nodeList;
}
private static string NodeString<T>(TreeNode<T> node)
{
return (node.parent != null ? NodeString(node.parent) + "->" : string.Empty) + node.thisItem;
}
private static bool ContainedInParent<T>(TreeNode<T> parent, T item)
{
var found = false;
if (parent != null)
{
if (parent.thisItem.Equals(item))
{
found = true;
}
else
{
found = ContainedInParent(parent.parent, item);
}
}
return found;
}
}
The output is:
CDG->LHR->CDG
CDG->LHR->JFK->CDG
CDG->LHR->JFK->DXB->JNB->SIN->SFO->JFK
CDG->LHR->JFK->DXB->JNB->SIN->SFO->BKK->SIN
CDG->LHR->JFK->DXB->JNB->SIN->SFO->BKK->DXB
CDG->LHR->JFK->DXB->JNB->SIN->SFO->BKK->CDG
.........
Related
I am trying to write a Function Previous(), to get the previous nodes of a Tree. The statement is: "We have a tree that is built using the class Node where an instance of the class represents a node in the tree. For simplicity, the node has a single data field of type int.
Your task is to write the extension method NodeExtensions.Previous() to find the previous element in the tree. You can write as many helper methods as you want, but don't change the signature of the extension method NodeExtensions.Previous()."
The node class goes like this:
public class Node
{
private List<Node> _children;
public Node(int data, params Node[] nodes)
{
Data = data;
AddRange(nodes);
}
public Node Parent { get; set; }
public IEnumerable<Node> Children
{
get
{
return _children != null
? _children
: Enumerable.Empty<Node>();
}
}
public int Data { get; private set; }
public void Add(Node node)
{
Debug.Assert(node.Parent == null);
if (_children == null)
{
_children = new List<Node>();
}
_children.Add(node);
node.Parent = this;
}
public void AddRange(IEnumerable<Node> nodes)
{
foreach (var node in nodes)
{
Add(node);
}
}
public override string ToString()
{
return Data.ToString();
}
}
I need to write an extension method like this:
using System;
using System.Linq;
public static class NodeExtensions
{
public static Node Previous(this Node node)
{
// TODO Implement extension method here
}
}
I have a test case:
using System;
using System.Text;
using NUnit.Framework;
public class NodeExtensionsTests
{
[Test]
public void Test()
{
// Test tree:
//
// 1
// +-2
// +-3
// +-4
// +-5
// +-6
// +-7
//
var lastNode = new Node(7);
var tree = new Node(
1,
new Node(
2,
new Node(3),
new Node(4)),
new Node(
5,
new Node(6),
lastNode));
// Expected output:
//
// 7
// 6
// 5
// 4
// 3
// 2
// 1
//
var n = lastNode;
while (n != null)
{
Console.WriteLine(n.Data);
n = n.Previous();
}
// Test
//
n = lastNode;
Assert.AreEqual(7, n.Data);
n = n.Previous();
Assert.AreEqual(6, n.Data);
n = n.Previous();
Assert.AreEqual(5, n.Data);
n = n.Previous();
Assert.AreEqual(4, n.Data);
n = n.Previous();
Assert.AreEqual(3, n.Data);
n = n.Previous();
Assert.AreEqual(2, n.Data);
n = n.Previous();
Assert.AreEqual(1, n.Data);
n = n.Previous();
Assert.IsNull(n);
}
}
Whatever I try, it either goes into an infinite loop, or just returns the root nodes instead of "all silblings". Can someone help me here?
I think this will work for you
public static class NodeExtensions
{
public static Node Previous(this Node node)
{
if (node.Parent == null) { return null; }
var brothers = (List<Node>) node.Parent.Children;
var index = brothers.IndexOf(node);
if(index == 0)
{
return node.Parent;
}
else
{
var next = brothers[index - 1];
while (next.Children.Any())
{
next = next.Children.Last();
}
return next;
}
}
}
here i have the following code and input that prints a tree structure. My question is how can i make it so that the nodes and leafs that have the value "Unavailable" are skipped from being printed.
namespace Tree{public class TreeNode<T>
{
private T value;
private bool hasParent;
private List<TreeNode<T>> children;
public TreeNode(T value)
{
if (value == null)
{
throw new ArgumentNullException("Cannot insert null value");
}
this.value = value;
this.children = new List<TreeNode<T>>();
}
public T Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public int ChildrenCount
{
get
{
return this.children.Count;
}
}
public void AddChild(TreeNode<T> child)
{
if (child == null)
{
throw new ArgumentNullException("Cannot insert null value");
}
if (child.hasParent)
{
throw new ArgumentException("The node already has a parent");
}
child.hasParent = true;
this.children.Add(child);
}
public TreeNode<T> GetChild(int index)
{
return this.children[index];
}
}
public class Tree<T>
{
private TreeNode<T> root;
public Tree(T value)
{
if (value == null)
{
throw new ArgumentNullException("Cannot insert null value");
}
this.root = new TreeNode<T>(value);
}
public Tree(T value, params Tree<T>[] children) : this(value)
{
foreach (Tree<T> child in children)
{
this.root.AddChild(child.root);
}
}
public TreeNode<T> Root
{
get
{
return this.root;
}
}
private void PrintDFS(TreeNode<T> root, string spaces)
{
if (this.root == null)
{
return;
}
Console.WriteLine(spaces + root.Value);
TreeNode<T> child = null;
for (int i = 0; i < root.ChildrenCount; i++)
{
child = root.GetChild(i);
PrintDFS(child, spaces + " ");
}
}
public void TraverseDFS()
{
this.PrintDFS(this.root, string.Empty);
}
}
public static class TreeExample
{
static void Main()
{
Tree<string> tree =
new Tree<string>("John",
new Tree<string>("Jasmine",
new Tree<string>("Jay"),
new Tree<string>("Unavailable")),
new Tree<string>("Unavailable",
new Tree<string>("Jack"),
new Tree<string>("Jeremy")),
new Tree<string>("Johanna")
);
tree.TraverseDFS();
}
}}
right now it prints :(John, (Jasmine, (Jay), (Unavailable)), (Unavailable, (Jack, (Jeremy))), (Johanna))
I need it to print :(John, (Jasmine, (Jay)), (Johanna))
So basically skip every leaf with the value "Unavailable" and every node with the value "Unavailable" and all children from that node
Thanks !
This should work:
private void PrintDFS(TreeNode<T> root, string spaces)
{
if (this.root == null
|| "Unavailable" == root.Value.ToString())
{
return;
}
...
The accepted answer is a literally correct answer to the question, but it bakes in logic about what to do with the tree into the tree itself. A tree is a kind of collection or data structure, and you don't often see a List or Dictionary that is able to print itself. Instead the collection provides the right methods to get or change its contents so that you can do what you want.
In your case, you could do something like the following:
public enum TreeVisitorResult {
SkipNode,
Continue
}
// the following two methods inside Tree<T>:
public void VisitNodes(Func<TreeNode<T>, int, TreeVisitorResult> visitor) {
VisitNodes(0, this.root, visitor);
}
private void VisitNodes(int depth, TreeNode<T> node,
Func<TreeNode<T>, int, TreeVisitorResult> visitor) {
if (node == null) {
return;
}
var shouldSkip = visitor(node, depth);
if (shouldSkip == TreeVisitorResult.SkipNode) {
return;
}
TreeNode<T> child = null;
for (int i = 0; i < node.ChildrenCount; i++) {
child = node.GetChild(i);
VisitNodes(depth + 1, child, visitor);
}
}
If you had this method, you could write the Print method outside of the Tree classes, as:
tree.VisitNodes((treeNode, depth) => { // <- this lambda will be called for every node
if (treeNode.Value == "Unavailable") { // <- no need to ToString or cast here, since
// we know that T is string here
return TreeVisitorResult.SkipNode;
} else {
var spaces = new string(' ', depth * 3);
Console.WriteLine(spaces + treeNode.Value);
}
});
I have a winforms treeview, I can read data automatically, (a node that is equal to key, and a node inside that is equal to value), but when reading object type, the values inside it are not going to be child of object node (key of object), (maybe I couldnt explain well, here is a screenshot and my methods.)
layer0 needs to be inside textures and scale needs to be inside display
My Json:
{
"parent": "builtin/generated",
"textures": {
"layer0": "mm:items/iron_dust"
},
"display": {
"scale": [ 1.7, 1.7, 1.7 ]
}
}
My method to auto detect(not all mine actually)
private void Form1_Load(object sender, EventArgs e)
{
StreamReader reader = new StreamReader(path);
string json = reader.ReadToEnd();
reader.Close();
JObject obj = JObject.Parse(json);
getAllProperties(obj);
}
void getAllProperties(JToken children)
{
TreeNode mainNode = treeView1.Nodes[0];
mainNode.Text = Path.GetFileNameWithoutExtension(path);
foreach (JToken child in children.Children())
{
var property = child as JProperty;
if (property != null)
{
if (property.Value.Type == JTokenType.String)
{
TreeNode keyNode = mainNode.Nodes.Add(property.Name);
keyNode.Nodes.Add(property.Value.ToString());
}
if (property.Value.Type == JTokenType.Array)
{
JArray array = (JArray)property.Value;
TreeNode node = mainNode.Nodes.Add(property.Name);
for (int i = 0; i < array.Count; i++)
{
node.Nodes.Add(array[i].ToString());
}
}
if (property.Value.Type == JTokenType.Object)
{
TreeNode topNode = mainNode.Nodes.Add(property.Name.ToString());
foreach (var item in property)
{
if (item.Type == JTokenType.String)
{
if (property.Value.Type == JTokenType.String)
{
TreeNode keyNode = topNode.Nodes.Add(property.Name);
keyNode.Nodes.Add(property.Value.ToString());
}
if (property.Value.Type == JTokenType.Array)
{
JArray array = (JArray)property.Value;
TreeNode node = topNode.Nodes.Add(property.Name);
for (int i = 0; i < array.Count; i++)
{
node.Nodes.Add(array[i].ToString());
}
}
}
}
}
// Console.WriteLine(property.Name + ":" + property.Value);//print all of the values
}
getAllProperties(child);
}
}
}
I tried to get parent, but it didnt have name and value properties :S.
Any help?
(Sorry for language mistakes)
The problem is that, as you recursively descend the JToken hierarchy, you also need to recursively descend the TreeNode hierarchy you are creating, adding child nodes to the parent node just created, rather than the root node, along the lines of Recursion, parsing xml file with attributes into treeview c#.
Thus if you do:
private void Form1_Load(object sender, EventArgs e)
{
using (var reader = new StreamReader(path))
using (var jsonReader = new JsonTextReader(reader))
{
var root = JToken.Load(jsonReader);
DisplayTreeView(root, Path.GetFileNameWithoutExtension(path));
}
}
private void DisplayTreeView(JToken root, string rootName)
{
treeView1.BeginUpdate();
try
{
treeView1.Nodes.Clear();
var tNode = treeView1.Nodes[treeView1.Nodes.Add(new TreeNode(rootName))];
tNode.Tag = root;
AddNode(root, tNode);
treeView1.ExpandAll();
}
finally
{
treeView1.EndUpdate();
}
}
private void AddNode(JToken token, TreeNode inTreeNode)
{
if (token == null)
return;
if (token is JValue)
{
var childNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(token.ToString()))];
childNode.Tag = token;
}
else if (token is JObject)
{
var obj = (JObject)token;
foreach (var property in obj.Properties())
{
var childNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(property.Name))];
childNode.Tag = property;
AddNode(property.Value, childNode);
}
}
else if (token is JArray)
{
var array = (JArray)token;
for (int i = 0; i < array.Count; i++)
{
var childNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(i.ToString()))];
childNode.Tag = array[i];
AddNode(array[i], childNode);
}
}
else
{
Debug.WriteLine(string.Format("{0} not implemented", token.Type)); // JConstructor, JRaw
}
}
You will get the following tree view structure:
Here is my crack at it. The output is identical to Notepad++'s JSTool plug-in:
The code is structured as a TreeView extension:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Windows.Forms;
namespace TestDLApp.Utilities.Extensions
{
public static class ObjectToTreeView
{
private sealed class IndexContainer
{
private int _n;
public int Inc() => _n++;
}
private static void FillTreeView(TreeNode node, JToken tok, Stack<IndexContainer> s)
{
if (tok.Type == JTokenType.Object)
{
TreeNode n = node;
if(tok.Parent != null)
{
if(tok.Parent.Type == JTokenType.Property)
{
n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type.ToString()}>");
}
else
{
n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type.ToString()}>");
}
}
s.Push(new IndexContainer());
foreach (var p in tok.Children<JProperty>())
{
FillTreeView(n, p.Value, s);
}
s.Pop();
}
else if (tok.Type == JTokenType.Array)
{
TreeNode n = node;
if(tok.Parent != null)
{
if (tok.Parent.Type == JTokenType.Property)
{
n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type.ToString()}>");
}
else
{
n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type.ToString()}>");
}
}
s.Push(new IndexContainer());
foreach (var p in tok)
{
FillTreeView(n, p, s);
}
s.Pop();
}
else
{
var name = string.Empty;
var value = JsonConvert.SerializeObject(((JValue)tok).Value);
if (tok.Parent.Type == JTokenType.Property)
{
name = $"{((JProperty)tok.Parent).Name} : {value}";
}
else
{
name = $"[{s.Peek().Inc()}] : {value}";
}
node.Nodes.Add(name);
}
}
public static void SetObjectAsJson<T>(this TreeView tv, T obj)
{
tv.BeginUpdate();
try
{
tv.Nodes.Clear();
var s = new Stack<IndexContainer>();
s.Push(new IndexContainer());
FillTreeView(tv.Nodes.Add("ROOT"), JsonConvert.DeserializeObject<JToken>(JsonConvert.SerializeObject(obj)), s);
s.Pop();
}
finally
{
tv.EndUpdate();
}
}
}
}
You can call it as so:
treeView1.SetObjectAsJson(new MyNeatObject());
I've a custom collection, which is a simple implementation encapsulating List<>:
[DebuggerDisplay("Count = {Count}")]
[Serializable()]
[ProtoInclude(100, typeof(SimpleTreeNodeList<>))]
public class SimpleList<T> : IList<T>, ICollection<T>, IEnumerable<T>, ICollection
{
... all methods redirect to a private List<T> ...
}
The reason for this is that I need to override the Add method, which isn't possible for a standard List. I need to create a tree, and the collection contains a list of children. When addin an element this the collection, I need to bind it to the parent.
So, I'm inheriting this SimpleList<T> class in SimpleTreeNodeList<>
If I serialize / deserilalize a SimpleList<T>, it works like a charm.
But if serialize / deserilalize a SimpleTreeNodeList<T> it doesn't work : no error, but the collection is empty when deserialized.
I don't understand why, as for other type it works correctly ?
I've read I've to set ProtoInclude attribute on the base class, it's what I've done but still the same problem
This is the implementation code:
[CollectionDataContract(IsReference = true)]
[Serializable]
[ProtoContract]
public class SimpleTreeNodeList<T> : SimpleList<SimpleTreeNode<T>>
{
#region CTor
public SimpleTreeNodeList()
: base()
{
}
public SimpleTreeNodeList(int capacity)
: base(capacity)
{
}
public SimpleTreeNodeList(SimpleTreeNode<T> parent)
{
this.Parent = parent;
}
#endregion
[IgnoreDataMember]
[ProtoMember(1, AsReference = true)]
public SimpleTreeNode<T> Parent { get; set; }
public override void Add(SimpleTreeNode<T> node)
{
base.Add(node);
node.Parent = Parent;
}
public void AddRange(IEnumerable<SimpleTreeNode<T>> collection)
{
foreach (var node in collection)
this.Add(node);
}
public override void Insert(int position, SimpleTreeNode<T> node)
{
base.Insert(position, node);
node.Parent = this.Parent;
}
public override void InsertRange(int position, IEnumerable<SimpleTreeNode<T>> nodes)
{
base.InsertRange(position, nodes);
foreach (var node in nodes)
node.Parent = this.Parent;
}
public SimpleTreeNode<T> Add(T Value)
{
SimpleTreeNode<T> node = new SimpleTreeNode<T>(Parent);
node.Value = Value;
base.Add(node);
return node;
}
public void Sort(Comparison<T> comparison)
{
this.Sort((x, y) => comparison(x, y));
}
public override string ToString()
{
return "Count=" + Count.ToString();
}
}
My simple test case:
[Test]
public void TestSimpleTreeNodeListSerialization()
{
var data = new SimpleTreeNodeList<string>();
data.Add("Un");
data.Add("Deux");
data.Add("Trois");
var path = Path.GetTempFileName();
try
{
File.WriteAllBytes(path, serialize(data));
var data2 = deserialize<SimpleTreeNodeList<string>>(File.ReadAllBytes(path));
Assert.IsNotNull(data2);
Assert.AreEqual(3, data2.Count);
for (int i = 0; i < data.Count; i++)
{
Assert.AreEqual(data[i].Value, data2[i].Value);
}
}
finally
{
if (File.Exists(path))
File.Delete(path);
}
}
private byte[] serialize<T>(T data)
{
var formatter = Serializer.CreateFormatter<T>();
using (var stream = new System.IO.MemoryStream())
{
formatter.Serialize(stream, data);
return stream.ToArray();
}
}
private T deserialize<T>(byte[] data)
{
var formatter = Serializer.CreateFormatter<T>();
using (var stream = new System.IO.MemoryStream(data))
{
return (T)formatter.Deserialize(stream);
}
}
I need to create a product catalog, in tree type.
every tree node presents by a ID(string), the functions on the tree data only 2:
getChild(string ID), give a ID, get children (no need include childrens'
children), if ID is null, get all root nodes
getParent(string ID), return parent ID if have, or null if is root
Since once the tree decided, will not change, so I think put all code in static will be best.
So I start to try use Dictionary
"id": {parent:ID, child:[id2, id3, id4....]}
Since theres about 1000+ catalog, I found I quickly mess myself up, lots of mistake in the static data, and make final result on usable. Also, now I only wrote dozens and the code is looking like mess.
Please advice a way create this simple catalog tree with high performance. Thanks
Just make a class out of it.
UPDATED:
class TreeNode : IEnumerable<TreeNode>
{
private readonly Dictionary<string, TreeNode> _children =
new Dictionary<string, TreeNode>();
public readonly string ID;
public TreeNode Parent { get; private set; }
public TreeNode(string id)
{
this.ID = id;
}
public TreeNode GetChild(string id)
{
return this._children[id];
}
public void Add(TreeNode item)
{
if (item.Parent != null)
{
item.Parent._children.Remove(item.ID);
}
item.Parent = this;
this._children.Add(item.ID, item);
}
public IEnumerator<TreeNode> GetEnumerator()
{
return this._children.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public int Count
{
get { return this._children.Count; }
}
}
Usage will be fairly simple to statically define:
var tree = new TreeNode("Root")
{
new TreeNode("Category 1")
{
new TreeNode("Item 1"),
new TreeNode("Item 2"),
new TreeNode("Item 3"),
},
new TreeNode("Category 2")
{
new TreeNode("Item 1"),
new TreeNode("Item 2"),
new TreeNode("Item 3"),
new TreeNode("Item 4"),
}
};
Edit
Some more functionality for even easier creation...
public static TreeNode BuildTree(string tree)
{
var lines = tree.Split(new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries);
var result = new TreeNode("TreeRoot");
var list = new List<TreeNode> { result };
foreach (var line in lines)
{
var trimmedLine = line.Trim();
var indent = line.Length - trimmedLine.Length;
var child = new TreeNode(trimmedLine);
list[indent].Add(child);
if (indent + 1 < list.Count)
{
list[indent + 1] = child;
}
else
{
list.Add(child);
}
}
return result;
}
public static string BuildString(TreeNode tree)
{
var sb = new StringBuilder();
BuildString(sb, tree, 0);
return sb.ToString();
}
private static void BuildString(StringBuilder sb, TreeNode node, int depth)
{
sb.AppendLine(node.ID.PadLeft(node.ID.Length + depth));
foreach (var child in node)
{
BuildString(sb, child, depth + 1);
}
}
Usage:
var tree = TreeNode.BuildTree(#"
Cat1
Sub1
Item1
Item2
Item3
Sub2
Item1
Item2
Cat2
Sub1
Sub2
Item1
Item2
Sub3
Item1
Cat3
Cat4");
I created a Node class that could be helpfull. It is fast and has some extra properties, like:
Ancestors
Descendants
Siblings
Level of the node
Parent
Root
Etc.
You can write a simple binary tree , I wrote some Pseudo code beloew:
class TreeNode {
TreeNode Right;
TreeNode Left;
int id;
//...
}
class BinTree {
void Insert(TreeNode node)
{
while(true) {
if(node.id > target.id) {
if(target.Right != null) {
target = target.Right;
continue;
}
else {
target.Right = node;
break;
}
}
else if(node.id < target.id) {
if(target.Left != null) {
target = target.Left;
continue;
}
else {
target.Left = node;
break;
}
}
else {
throw new ArgumentException("Duplicated id");
}
}
}
TreeNode Search(int id)
{
TreeNode target = root;
while(target != null) {
if(id > target.id) {
target = target.Right;
}
else if(id < target.id) {
target = target.Left;
}
else {
return target;
}
}
return null;
}
}
But if your data count is very large, maybe AVL tree is more efficient