I have created a binary search tree, and am stuck on how to delete a node from my tree. My code currently looks like this:
public class Node
{
public int value;
public int id;
public Node left, right;
public Node(int identifier, int v)
{
id = identifier;
value = v;
left = right = null;
}
}
public class BinaryTree
{
public static Node head;
public virtual Node insert(Node node,int id, int value)
{
if (node == null)
{
return (new Node(id, value));
}
else
{
if (value <= node.value)
{
node.left = insert(node.left, id, value);
}
else
{
node.right = insert(node.right, id, value);
}
return node;
}
}
public virtual int maxvalue(Node node)
{
Node current = node;
while (current.right != null)
{
current = current.right;
}
return (current.id);
}
public static void Main(string[] args)
{
BinaryTree bt = new BinaryTree();
Node root = null;
root = bt.insert(root, 4, 5);
root = bt.insert(root, 9, 6);
root = bt.insert(root, 16, 3);
Console.WriteLine(bt.maxvalue(root));
root = bt.insert(root, 12, 8);
Console.WriteLine(bt.maxvalue(root));
Console.WriteLine(bt.maxvalue(root));
}
}
What I want to do is, every time I print out the id of the node with the highest value, I then want delete that node from my BST. However, I do not know how to implement this function, so if anyone knows how, I would appreciate it.
Related
** after print Dictionary all values are same. Why?? Where is the problem??**
** after print Dictionary all values are same. Why?? Where is the problem??**
** after print Dictionary all values are same. Why?? Where is the problem??**
** after print Dictionary all values are same. Why?? Where is the problem??**
In Dictionary I added Key as int and value as an object(Node)
In Dictionary I added Key as int and value as an object(Node)
In Dictionary I added Key as int and value as an object(Node)
In Dictionary I added Key as int and value as an object(Node)
using System;
using System.Collections.Generic;
using System.Linq;
namespace Tree1
{
public class Node
{
public int data;
public Node left, right;
}
public class NewNode
{
Node node = new Node();
public Node createNode(int key)
{
node.data = key;
//Console.WriteLine(key);
node.left = node.right = null;
return node;
}
}
public class Print
{
Node node = new Node();
public void inorder(Node root)
{
if (root == null)
return;
inorder(node.left);
//Console.WriteLine(node.data+" ");
inorder(node.right);
}
}
public class BinaryTree
{
Node root = new Node();
NewNode newNode = new NewNode();
public Node createTree(int[] parent, int n)
{
Dictionary<int, Node> map = new Dictionary<int, Node>();
for (int i = 0; i<n; i++)
{
map.Add(i,newNode.createNode(i));
//Console.WriteLine(map.Keys + " " + map[i].data);
}
foreach (var pair in map)
{
int key = pair.Key;
Node value = pair.Value;
Console.WriteLine(key + "/" + value.data);
}
root = null;
for(int i = 0; i<n; i++)
{
if(parent[i] == -1)
{
root = map[i];
}
else
{
Node ptr = map[parent[i]];
//Console.WriteLine(parent[i]);
//Console.WriteLine(ptr.data);
if (ptr.left != null)
{
ptr.right = map[i];
}
else
{
ptr.left = map[i];
}
}
}
return root;
}
}
class Program
{
static void Main(string[] args)
{
int[] parent = new int[] { -1, 0, 0, 1, 2, 2, 4, 4};
BinaryTree binaryTree = new BinaryTree();
Node root = new Node();
root = binaryTree.createTree(parent, parent.Length);
Print print = new Print();
print.inorder(root);
Console.ReadLine();
}
}
}
[enter image description here][1]
You need a constructor in your node class.
public class Node
{
public int data;
public Node left, right;
public Node(int data){
this.data = data;
}
}
Then when you create a new Node, you can pass the value you want to be set as data.
var newNode = new Node(value);
I have database table object which is:
[Table("TreeViewDb")]
public class TreeViewDb
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
}
And I have a view model whcih is :
public class TreeView
{
public TreeView()
{
Children = new List<TreeView>();
}
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
// children
public List<TreeView> Children { get; set; }
}
Now I need to save TreeView to the database. During save children or children under children to the nth Level. But my below method only goes to level 3. How can I go to nth Level to save child and parent objects with recursive way?
public bool SaveOrUpdateTreeView(TreeView viewModel)
{
// Level 1
var parentModel = new TreeViewDb
{
Id = viewModel.Id,
ParentId = viewModel.ParentId,
Name = viewModel.Name
};
// Save or update object and return primary key
var parentId = _dataRepository.SaveOrUpdateTreeView(parentModel);
// Level 2
foreach (var child in viewModel.Children)
{
var childModel = new TreeViewDb
{
Id = viewModel.Id,
ParentId = parentId, // Parent Primary Key
Name = viewModel.Name
};
// Save or update object and return primary key
var childId = _dataRepository.SaveOrUpdateTreeView(childModel);
// Level 3
foreach (var grandChild in child.Children)
{
var grandChildModel = new TreeViewDb
{
Id = viewModel.Id,
ParentId = childId, // Child Primary Key
Name = viewModel.Name
};
_dataRepository.SaveOrUpdateTreeView(grandChildModel);
}
}
return true;
}
There you go:
use a Stack including item depth
iterate nodes in order
decide to save it or not
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace zzzzzzzz
{
internal static class Program
{
private static void Main(string[] args)
{
var node = new Node("node 0 # level 0")
{
new Node("node 1 # level 1")
{
new Node("node 2 # level 2")
{
new Node("node 3 # level 3")
{
new Node("node 4 # level 4")
}
}
},
new Node("node 5 # level 1")
{
new Node("node 6 # level 2")
{
new Node("node 7 # level 3")
}
}
};
var stack = new Stack<(Node, int)>();
stack.Push((node, 0));
while (stack.Any())
{
var (current, depth) = stack.Pop();
ProcessNode(current, depth);
foreach (var item in current.Reverse())
{
stack.Push((item, depth + 1));
}
}
}
private static void ProcessNode(Node node, int depth)
{
Console.Write($"{new string('\t', depth)}{node}");
var color = Console.ForegroundColor;
Console.ForegroundColor = depth < 3 ? ConsoleColor.Green : ConsoleColor.Red;
Console.Write($" {(depth < 3 ? "SAVED" : "IGNORED")}{Environment.NewLine}");
Console.ForegroundColor = color;
}
}
public class Node : IList<Node>
{
public Node(string text)
{
Text = text;
}
public string Text { get; set; }
private IList<Node> List { get; } = new List<Node>();
public IEnumerator<Node> GetEnumerator()
{
return List.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) List).GetEnumerator();
}
public void Add(Node item)
{
List.Add(item);
}
public void Clear()
{
List.Clear();
}
public bool Contains(Node item)
{
return List.Contains(item);
}
public void CopyTo(Node[] array, int arrayIndex)
{
List.CopyTo(array, arrayIndex);
}
public bool Remove(Node item)
{
return List.Remove(item);
}
public int Count => List.Count;
public bool IsReadOnly => List.IsReadOnly;
public int IndexOf(Node item)
{
return List.IndexOf(item);
}
public void Insert(int index, Node item)
{
List.Insert(index, item);
}
public void RemoveAt(int index)
{
List.RemoveAt(index);
}
public Node this[int index]
{
get => List[index];
set => List[index] = value;
}
public override string ToString()
{
return $"{nameof(Text)}: {Text}";
}
}
}
You can create an generic iterator that allow you to iterate over all the nodes in the tree:
public static IEnumerable<(T Parent, T Node, int Level)> BreadthFirst<T>(T self, Func<T, IEnumerable<T>> selector)
{
var queue = new Queue<(T Parent, T Node, int Level)>();
queue.Enqueue((self, self, 0));
while (queue.Count > 0)
{
var current = queue.Dequeue();
yield return current;
var node = current.Node;
var level = current.Level + 1;
foreach (var child in selector(node))
{
queue.Enqueue((node, child, level));
}
}
}
Called like
var nodes = BreadthFirst(viewModel, v => v.Children).Where(t => t.Level < 3);
The root node will have itself as the parent, so you will need to check for this if you want to handle it some other way.
The problem goes like this:
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.Next() to find the next 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.Next().
I have this Node class:
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();
}
}
The solution should be a extension method such as this
public static Node Next(this Node node)
{
}
The code I tried:
public static Node Next(this Node node)
{
var newNode = NextLargerElement(node, node.Data);
return newNode;
}
public static Node res;
public static Node NextLargerElementUtil(Node root, int x)
{
if (root == null)
return null;
if (root.Data > x)
if ((res == null || (res).Data > root.Data))
res = root;
foreach (var children in root.Children)
{
NextLargerElementUtil(children, x);
}
return res;
}
static Node NextLargerElement(Node root, int x)
{
res = null;
NextLargerElementUtil(root, x);
return res;
}
Here is a testing case:
[Test]
public void Test()
{
// Test tree:
//
// 1
// +-2
// +-3
// +-4
// +-5
// +-6
// +-7
//
var root = new Node(
1,
new Node(
2,
new Node(3),
new Node(4)),
new Node(
5,
new Node(6),
new Node(7)));
// Expected output:
//
// 1
// 2
// 3
// 4
// 5
// 6
// 7
//
var n = root;
while (n != null)
{
Console.WriteLine(n.Data);
n = n.Next();
}
// Test
//
n = root;
Assert.AreEqual(1, n.Data);
n = n.Next();
Assert.AreEqual(2, n.Data);
n = n.Next();
Assert.AreEqual(3, n.Data);
n = n.Next();
Assert.AreEqual(4, n.Data);
n = n.Next();
Assert.AreEqual(5, n.Data);
n = n.Next();
Assert.AreEqual(6, n.Data);
n = n.Next();
Assert.AreEqual(7, n.Data);
n = n.Next();
Assert.IsNull(n);
}
You can use Equals to backtrack your current node position in the tree and return it's parent's next child, if any, if there is not one then you need to backtrack the current node parent position and so on:
public static Node Next(this Node node)
{
if(node.Children != null && node.Children.Any())
{
return node.Children.First();
}
// "backtracking", also can be done recursively
var parent = node.Parent;
while(parent != null)
{
var returnNext = false; // return next element in Children if current is node
foreach (var element in parent.Children)
{
if(returnNext)
{
return element;
}
if(element == node)
{
returnNext = true;
node = parent; // to find parent's position if there is no next child
}
}
parent = parent.Parent;
}
return null;
}
how to write billions of data into a trie with less memory
I want to extract some infomation from news like company names,so I write billions of company names into a trie,but it needs much memory and throw out of memory exception,I don't know how to solve it,so anyone can help,thanks in advance.
public class Node
{
public char Value { get; set; }
public List<Node> Children { get; set; }
public int Depth { get; set; }
public string Code { get; set; }
public bool Terminal { get; set; }
public Node(char value, int depth)
{
Value = value;
Depth = depth;
Children = new List<Node>();
}
public Node FindChildNode(char c)
{
foreach (var child in Children)
if (child.Value == c)
return child;
return null;
}
}
public class Trie
{
private Node _root;
public Trie()
{
_root = new Node('^',0);
}
public Node Prefix(string s)
{
var currentNode = _root;
var result = currentNode;
foreach (var c in s)
{
currentNode = currentNode.FindChildNode(c);
if (currentNode == null)
break;
result = currentNode;
}
return result;
}
public void Insert(string randomLength,string code)
{
var commonPrefix = Prefix(randomLength);
var current = commonPrefix;
for (var i = current.Depth; i < s.Length; i++)
{
var newNode = new Node(s[i], current.Depth + 1);
if (i+1==s.Length)
{
newNode.Terminal = true;
newNode.Code = code;
}
current.Children.Add(newNode);
current = newNode;
}
}
}
Trie t=new Trie();
t.Insert("C","ABCG00DFD");
The aboved statement run 1000000000 Loops and the "C" can be replaced with different string with different length,as the loops increasing,it throw out of memory exception,so how to avoid or change it?
Have a go at this Trie and see if you can get it to work for what you need:
public class Trie : Dictionary<char, Trie>
{
public void Add(string value)
{
var c = String.IsNullOrEmpty(value) ? '\0' : value[0];
if (!this.ContainsKey(c))
{
this[c] = new Trie();
}
if (c != '\0')
{
this[c].Add(value.Substring(1));
}
}
}
I have write a C# code to insert data to a doubly linked list and to delete a node. It is working and I can traverse the list from last node to first. But I can not traverse the list from first node to the last. I can not find the mistake I have made. Following is my code.
class Node
{
public string data { get; set; }
public Node next { get; set; }
public Node previous { get; set; }
public Node(string data)//first node)
{
this.data = data;
this.next = null;
this.previous = null;
}
public Node(string data, Node next,Node previous)
{
this.data = data;
this.next = next;
this.previous = previous;
}
}
class doublyLinkedList
{
private Node first;
private Node last;
private int size;
public doublyLinkedList()
{
this.first = null;
this.last = null;
this.size = 0;
}
public bool isEmpty
{
get { return this.size == 0; }
}
public int count
{
get { return this.size; }
}
public void Add(string o)
{
Node current = this.last;
if (this.isEmpty)
{
this.first = new Node(o);
this.last = new Node(o);
}
else
{
current.next = new Node(o, current.next,current);
last = current.next;
Console.WriteLine("first " + first.data + "last " + last.data + "previous " + last.previous.data);
}size++;
}
public object getFirst()
{
return first.data;
}
public string remove()
{
Node current = this.last;
current.previous.next = null;
object removedElement = current.data;
string reEle = ((String)(removedElement).ToString());
current = current.previous;
size--;
return reEle;
}
public void TraverseFront()
{
Node current = this.first;
string str = current.data;
Console.WriteLine("first " + str);
Node current1 = first.next;
string str1 = first.next.data;
string question = str + str1;
Console.WriteLine(question)
}
}
Your problem is when you insert the first object. You need to set last to the same instance as first, as at the moment you are disconnecting the first object (this.first.next is always null), change it from:
this.last = new Node(o);
to:
this.last = this.first;