How to create a binary tree - c#

I did'nt mean binary search tree.
for example,
if I insert values 1,2,3,4,5 in to a binary search tree the inorder traversal will give
1,2,3,4,5 as output.
but if I insert the same values in to a binary tree, the inorder traversal should give
4,2,5,1,3 as output.
Binary tree can be created using dynamic arrays in which for each element in index n,
2n+1 and 2n+2 represents its left and right childs respectively.
so representation and level order traversal is very easy here.
but I think, in-order,post-order,pre-order is difficult.
my question is how can we create a binary tree like a binary search tree.
ie.
have a tree class which contains data, left and right pointers instead of arrays.
so that we can recursively do traversal.

If I understand you correctly, you want to create a binary tree from an array
int[] values = new int[] {1, 2, 3, 4, 5};
BinaryTree tree = new BinaryTree(values);
this should prepopulate the binary tree with the values 1 - 5 as follows:
1
/ \
2 3
/ \
4 5
this can be done using the following class:
class BinaryTree
{
int value;
BinaryTree left;
BinaryTree right;
public BinaryTree(int[] values) : this(values, 0) {}
BinaryTree(int[] values, int index)
{
Load(this, values, index);
}
void Load(BinaryTree tree, int[] values, int index)
{
this.value = values[index];
if (index * 2 + 1 < values.Length)
{
this.left = new BinaryTree(values, index * 2 + 1);
}
if (index * 2 + 2 < values.Length)
{
this.right = new BinaryTree(values, index * 2 + 2);
}
}
}

Since I have not received any answers to the question which I asked, I will post my own implementaion of the binary tree using arrays.
now I know that array implementaion is easier than i thought ,but still i dont know how to implement the same using linked lists.
the code is in c#
class BinaryTree
{
private static int MAX_ELEM = 100; //initial size of the array
int lastElementIndex;
int?[] dataArray;
public BinaryTree()
{
dataArray = new int?[MAX_ELEM];
lastElementIndex = -1;
}
//function to insert data in to the tree
//insert as a complete binary tree
public void insertData(int data)
{
int?[] temp;
if (lastElementIndex + 1 < MAX_ELEM)
{
dataArray[++lastElementIndex] = data;
}
else
{ //double the size of the array on reaching the limit
temp = new int?[MAX_ELEM * 2];
for (int i = 0; i < MAX_ELEM; i++)
{
temp[i] = dataArray[i];
}
MAX_ELEM *= 2;
dataArray = temp;
dataArray[++lastElementIndex] = data;
}
}
//internal function used to get the left child of an element in the array
int getLeftChild(int index) {
if(lastElementIndex >= (2*index+1))
return (2*index + 1);
return -1;
}
//internal function used to get the right child of an element in the array
int getRightChild(int index) {
if(lastElementIndex >= (2*index+2))
return (2*index + 2);
return -1;
}
//function to check if the tree is empty
public bool isTreeEmpty() {
if (lastElementIndex == -1)
return true;
return false;
}
//recursive function for inorder traversal
public void traverseInOrder(int index) {
if (index == -1)
return;
traverseInOrder(getLeftChild(index));
Console.Write("{0} ", dataArray[index]);
traverseInOrder(getRightChild(index));
}
//recursive function for preorder traversal
public void traversePreOrder(int index) {
if (index == -1)
return;
Console.Write("{0} ", dataArray[index]);
traversePreOrder(getLeftChild(index));
traversePreOrder(getRightChild(index));
}
//recursive function for postorder traversal
public void traversePostOrder(int index) {
if (index == -1)
return;
traversePostOrder(getLeftChild(index));
traversePostOrder(getRightChild(index));
Console.Write("{0} ", dataArray[index]);
}
//function to traverse the tree in level order
public void traverseLevelOrder()
{
Console.WriteLine("\nPrinting Elements Of The Tree In Ascending Level Order\n");
if (lastElementIndex == -1)
{
Console.WriteLine("Empty Tree!...press any key to return");
Console.ReadKey();
return;
}
for (int i = 0; i <= lastElementIndex; i++)
{
Console.Write("{0} ", dataArray[i]);
}
Console.WriteLine("\n");
}
}

The tree class declaration part is, certainly, not the difficulty here. You basically stated exactly how to declare it, in the question:
class BinaryTree
{
private:
int data;
BinaryTree *left, *right;
};
This supports various forms of traversal, like so:
void Inorder(const BinaryTree *root)
{
if(root == 0)
return;
Inorder(root->left);
printf("now at %d\n", root->data);
Inorder(root->right);
}
You should be able to deduce pre- and post-order traversals from that. In a real implementation, the tree would probably be templated to store random data, the traversal routines would be more general (with a user-data input, or perhaps user-supplied per-node callback, or whatever), of course.

If you're after source for a comprehensive BinaryTree implementation you can learn from have a look at The C5 Generic Collection Library.

class BstNode
{
public int data;
public BstNode(int data)
{
this.data = data;
}
public BstNode left;
public BstNode right;
}
class Program
{
public static BstNode Insert(BstNode root, int data)
{
if (root == null) root = new BstNode(data);
else if (data <= root.data) root.left = Insert(root.left, data);
else if (data > root.data) root.right = Insert(root.right, data);
return root;
}
public static void Main(string[] args)
{
// create/insert into BST
BstNode Root = null;
Root = Insert(Root, 15);
Root = Insert(Root, 10);
Root = Insert(Root, 20);
Root = Insert(Root, 8);
Root = Insert(Root, 12);
Root = Insert(Root, 17);
Root = Insert(Root, 25);
}
}

Related

C# Radix Sort implementation in LinkedList

i have a task to make a radix sort algorithm for a linkedlist class, i have an object "Info", which has int Year and double Price, i need to sort linked list by Year using radix sorting.
class Info
{
public int Year { get; set; }
public double Price { get; set; }
public Info() { }
public Info(int y, double p)
{
Year = y;
Price = p;
}
}
class Node
{
public Info Data { get; set; }
public Node Next { get; set; }
public Node(Info data, Node adress)
{
Data = data;
Next = adress;
}
}
class LinkedList
{
private Node First;
private Node Last;
private Node Current;
public LinkedList()
{
First = null;
Last = null;
Current = null;
}
}
And i have taken radix sort algorithm for integer from this site. Problem is, i don't know how to modify it to work with my linked class.
static void Sort(int[] arr)
{
int temp = 0;
int i, j;
int[] tmp = new int[arr.Length];
for (int shift = 31; shift > -1; --shift)
{
j = 0;
for (i = 0; i < arr.Length; ++i)
{
bool move = (arr[i] << shift) >= 0;
if (shift == 0 ? !move : move)
arr[i - j] = arr[i];
else
tmp[j++] = arr[i];
}
Array.Copy(tmp, 0, arr, arr.Length - j, j);
}
}
How to make it work with my linked class ?
Based on that code, arr and tmp would need to be linked lists. One issue with this approach is that moving a node requires keeping track of the previous nodes in order to move a node. A dummy head node could be used to provide a node previous to the first data node, or special case handing when moving a node to the start of a list. An alternative would be using two pointers (references) to nodes of temp lists, one where bit == 0, one where bit == 1, and then concatenating the two temp lists into a single list. Note this approach takes 32 passes. If the radix sort were based on a byte instead of a bit, it could be reduced to 4 passes, but would need 256 pointers to nodes for 256 lists.

Determine if a tree is balanced or not in linear time

The following programme returns whether a tree is balanced or not. A tree is said to be balanced if a path from the root to any leaf has the same length.
using System;
namespace BalancedTree
{
public class MainClass
{
static bool isBalanced(int[][] sons)
{
return isBalanced(sons, 0);
}
static bool isBalanced(int[][] sons, int startNode)
{
int[] children = sons[startNode];
int minHeight = int.MaxValue;
int maxHeight = int.MinValue;
bool allChildBalanced = true;
if(children.Length == 0)
return true;
else
{
foreach (int node in children)
{
int h = height(sons, node);
if(h > maxHeight)
maxHeight = h;
if(h < minHeight)
minHeight = h;
}
}
foreach (int node in children)
{
allChildBalanced = allChildBalanced && isBalanced(sons, node);
if(!allChildBalanced)
return false;
}
return Math.Abs(maxHeight - minHeight) < 2 && allChildBalanced;
}
static int height(int[][] sons, int startNode)
{
int maxHeight = 0;
foreach (int child in sons[startNode])
{
int thisHeight = height(sons, child);
if(thisHeight > maxHeight)
maxHeight = thisHeight;
}
return 1 + maxHeight;
}
public static void Main (string[] args)
{
int[][] sons = new int[6][];
sons[0] = new int[] { 1, 2, 4 };
sons[1] = new int[] { };
sons[2] = new int[] { 3, 5};
sons[3] = new int[] { };
sons[4] = new int[] { };
sons[5] = new int[] { };
Console.WriteLine (isBalanced(sons));
}
}
}
My problem is that my code is very inefficient, due to recursive calls to function
static int height(int[][] sons, int startNode)
making the time complexity exponential.
I know this can be optimised in case of a binary tree, but I'm looking for a way to optimise my programme in case of a general tree as described above.
One idea would be for instance to call function 'height' from the current node instead of startNode.
My only constraint is time complexity which must be linear, but I can use additional memory.
Sorry, but I have never done C#. So, there will be no example code.
However, it shouldn't be too hard for you to do it.
Defining isBalanced() recursively will never give best performance. The reason is simple: A tree can still be unbalanced, if all sub-trees are balanced. So, you can't just traverse the tree once.
However, your height() function already does the right thing. It visits every node in the tree only once to find the height (i.e. maximum length from the root to a leaf).
All you have to do is write a minDistance() function that finds the minimum length from the root to a leaf. You can do this using almost the same code.
With these functions a tree is balanced if and only if height(...)==minDistance(...).
Finally, you can merge both function into one that returns a (min,max) pair. This will not change time complexity but could bring down execution time a bit, if returning pairs is not too expensive in C#

Get the path between two items in array

I am trying to write a function to get the path between two items in array
this array represent the connectivities between the items
like a tree with no cycles for example:
A=[1, 3, 0, 3, 2]
A[0]=1 // node 0 is connected to node 1
A[1]=3 // node 1 is connected to node 3
A[2]=0 //node 2 is connected to node 0
and so on,
So now this array generates a graph like this <4---2---0----1---3>
And this function should get the path between two given indecies in the array
if given 4 & 1 the output should be list of [2,0]
So I want to help how to start building the algorithm for this function?
I tried this code
private List<int> getDirectlyConnectedNodes(int ind, int[] A)
{
List<int> directNeighbours = new List<int>();
for (int i = 0; i < A.Length; i++)
{
if ((A[i] == ind || A[ind] == i) && ind != i)
{
directNeighbours.Add(i);
}
}
return directNeighbours;
}
private List<int> getPath(int ind1, int ind2, int[] A, List<int> path)
{
List<int> directNeighbours= getDirectlyConnectedNodes(ind1, A);
foreach (int i in directNeighbours)
{
path.Add(i);
if (A[i] == ind2 || A[ind2] == i)
{
return path;
}
else
{
getPath(i, ind2, A, path);
}
}
return path;
}
You can find paths to root from both nodes, drop common part and join paths.
public static List<int> GetPath(int a,int b,int[] array) {
Stack<int> stacka=GetPathToRoot(a,array);
Stack<int> stackb=GetPathToRoot(b,array);
int lastCommonNode=-1;
while(stacka.Count>0&&stackb.Count>0&&stacka.Peek()==stackb.Peek()) {
lastCommonNode=stacka.Pop();
stackb.Pop();
}
List<int> list=new List<int>();
while(stacka.Count>1) {
list.Add(stacka.Pop());
}
list.Reverse();
if(stacka.Count>0&&stackb.Count>0) {
list.Add(lastCommonNode);
}
while(stackb.Count>1) {
list.Add(stackb.Pop());
}
return list;
}
private static Stack<int> GetPathToRoot(int a,int[] array) {
Stack<int> stack=new Stack<int>();
for(;;) {
stack.Push(a);
if(array[a]==a) {
break;
}
a=array[a];
}
return stack;
}
Can't you just start with the first index and keep going until you hit the second index? There doesn't seem to be any branching in your data structure, just a fixed path from one node to the next.
private IEnumerable<int> getPath(int ind1, int ind2, int[] A)
{
for (int ind = ind1; A[ind] != ind && A[ind] != ind2; ind = A[ind])
{
yield return A[ind];
}
}
You might need to tweak it to cover the false positive you get if there is no path between the specified nodes, but when there is a path it should find it.

Printing a binary tree in order

I have a problem to convert a sorted array to a binary tree. I think that I have done it. Now I just want to print all items after conversion to double check it.
My question is that my printing part doesn't print all items. Something is wrong in the method 'inOrderTraversalHelper'.
class Program
{
// Given an array where elements are sorted in ascending order,
// convert it to a height balanced BST
static int[] arr = new int[8] {1,2,3,4,5,6,7,8};
static TreeNode node { get; set; }
static void Main(string[] args)
{
node = SortedArrayToBST(arr, 0, arr.Length-1);
inOrderTraversal();
}
static void inOrderTraversal()
{
inOrderTraversalHelper(node);
}
static void inOrderTraversalHelper(TreeNode r)
{
if (r != null)
{
**// UPDATED**
inOrderTraversalHelper(r.leftNode);
Console.Write("{0} ", r.data);
inOrderTraversalHelper(r.rightNode);
}
}
static TreeNode SortedArrayToBST(int[] a,int start,int end)
{
if (start > end) return null;
int mid = (start + end) / 2;
TreeNode node = new TreeNode(a[mid]);
node.leftNode= SortedArrayToBST(a, start, mid-1);
node.rightNode = SortedArrayToBST(a, mid + 1, end);
return node;
}
}
public class TreeNode
{
public int data;
public TreeNode leftNode;
public TreeNode rightNode;
public TreeNode(int data)
{
this.data = data;
}
}
It's because you are storing the value of the index mid not the value at the index of mid:
int mid = (start + end) / 2;
TreeNode node = new TreeNode(mid);
You are calculating the value of mid and then passing it in as the data. Instead mid should be the index of the value you want. For, example if you had a data set where the data was ordered but non sequential you'd get even stranger results:
{-1,22,33,44,55,66,77,100}
So your code should probably look up the value at index mid instead:
var mid = (int)((start + end) / 2.0);
var node = new TreeNode(arr[mid]);
In SortedArrayToBST, you work with the index mid, rather than with the element a[mid], change:
TreeNode node = new TreeNode(mid);
to:
TreeNode node = new TreeNode(a[mid]);
In the call to the SortedArrayToBST function, you need to pass array size - 1, since the end condition in inclusive, change:
node = SortedArrayToBST(arr, 0, arr.Length);
to:
node = SortedArrayToBST(arr, 0, arr.Length-1);
Also, your inOrderTraversalHelper function isn't actually in-order, but rather post-order.

Adjust Range Search of BinaryTree to get the Outer Elements

I have a RedBlack [Balanced, sorted] Binary Tree and I am searching it to find all the values within the range [lower, upper].
public IEnumerable<TData> Range(
BinaryTree<TData> root,
IComparer<TData> comparer,
TData lower,
TData upper)
{
var stack = new Stack<State>(16);
BinaryTree<TData> here = root;
do
{
if (here == null)
{
if (stack.Count == 0)
break;
State popped = stack.Pop();
yield return popped.Data;
here = popped.Next;
continue;
}
if (comparer.Compare(here.Data, lower) < 0)
{
here = here.Right;
}
else if (comparer.Compare(here.Data, upper) > 0)
{
here = here.Left;
}
else
{
stack.Push(new State {Next = here.Right, Data = here.Data});
here = here.Left;
}
} while (true);
}
So with this code, if I were to have a tree built with the values
[0, 1, 4, 5, 6, 9],
and search for all elements within the range
[3, 8]
I would get the following results:
[4, 5, 6].
My question is how can I do about adjusting this algorithm in order to get the outer elements of the search? like this:
[1, 4, 5, 6, 9]
i.e. the value 3 lies between 1 and 4 in the tree, so I want to return 1, similarly the value 8 lies between 6 and 9 and I would want the value 9 to be includes in the result.
One catch is I don't want to restart the search from root
Currently implemented using NGenerics
[Edit]
Willing to accept a general algorithmic answer.
I'm not sure with what you are trying to populate the Red Black Tree. But if you are using array or stream of data (whose number of elements will not change) then you may go this by using Segment Tree
class SegmentTree
{
class Node
{
int max, min, s, e;
Node left, right;
#Override
public String toString()
{
String str = "Min: "+this.min+" Max: "+this.max+" "+this.s+"-"+this.e;
return str;
}
}
private Node root;
public SegmentTree() {}
public SegmentTree(int[] array)
{
add(array);
}
public void add(int[] array)
{
root = add(0, array.length-1, array);
}
private Node add(int s, int e, int[] array)
{
Node n = new Node();
n.s = s;
n.e = e;
if(n.s==n.e)
{
n.min = n.max = array[n.s];
return n;
}
int mid = s+(e-s)/2;
n.left = add(s, mid, array);
n.right = add(mid+1, e, array);
n.max = Math.max(n.left.max, n.right.max);
n.min = Math.min(n.left.min, n.right.min);
return n;
}
// Get the max value between the limits l and r (both inclusive)
public int getMax(int l, int r)
{
return getMax(root, l, r);
}
private int getMax(Node n, int l, int r)
{
if(l<=n.s && r>=n.e)
return n.max;
if(l>n.e || r<n.s)
return Integer.MIN_VALUE;
return Math.max(getMax(n.left, l, r), getMax(n.right, l, r));
}
public int getMin(int l, int r)
{
return getMin(root, l, r);
}
private int getMin(Node n, int l, int r)
{
if(l<=n.s && r>=n.e)
return n.min;
if(l>n.e || r<n.s)
return Integer.MAX_VALUE;
return Math.min(getMin(n.left, l, r), getMin(n.right, l, r));
}
}
NOTE
If there is increase or decrease in the data then you have to reconstruct the tree. If there is frequent insertion/ deletion/ updation then this is not at all a good choice.
This is very useful when you have set of data and on which you need to frequently check the values for the particular range.
I have given the example of storing both minimum and maximum value. You may store sum of values or any thing else in your Node
Apologize for writing code in JAVA :)

Categories

Resources