Merge two Binary trees - binary-search-tree

public int merge(BNode node, int array[], int i) {
if (node == null)
return i;
//Flatten left subtree
i = merge(node.left, array, i);
//Get data from the current node
array[i] = node.value;
//Flatten right subtree
i = merge(node.right, array, i + 1);
return i;
}
I'm trying to merge two binary trees and retain the BST property.
The approach im using is to flatten the trees and store them in arrays.
The function above flattens my first tree and stores it in the array[] .
I want a function which would take the rootnode and blank array[] as input and RETURNS me a flattened tree with all the nodes into an array.

As you are doing, if you want to merge 2 binary search tree, the best way is:
1)Flatten trees into sorted lists.
2)Merge lists.
3)Transform the merged list to a BST.
You can implement the function you are looking for easily this way:
BinarySearchTree* arrayToTree(int arr[], int start, int end) {
if (start > end) return NULL;
int mid = start + (end - start) / 2;
BinarySearchTree *node = new BinarySearchTree(arr[mid]);
node->left = arrayToTree(arr, start, mid-1);
node->right = arrayToTree(arr, mid+1, end);
return node;
}
BinarySearchTree* arrayToTree(int arr[], int n) {
return arrayToTree(arr, 0, n-1);
}

Related

Insert Unique element into trie

void insert(struct node *root, string s)
{
struct node *temp = root;
for(int i=0;i<s.length();i++)
{
if(temp->idx[s[i]-'a']==NULL)
temp->idx[s[i]-'a']=create();
temp = temp->idx[s[i]-'a'];
(temp->cnt)++;
}
temp->end=1;
}
So I am going to insert string to create a unique trie data structure, but this insert algortihm is not able to detect any duplicate string, can someone help me how this insert algorithm works only for inserting unique elements?
You can check for string duplicates using end property of struct node. Let's call find to this boolean method and add it as first line of insert method.
bool find(struct node *root, string s)
{
struct node *temp = root;
for(int i=0;i<s.length();i++)
{
if(temp->idx[s[i]-'a']==NULL)
return false;
temp = temp->idx[s[i]-'a'];
}
return temp->end;
}
void insert(struct node *root, string s)
{
if(!find(root, s)) return;
struct node *temp = root;
for(int i=0;i<s.length();i++)
{
if(temp->idx[s[i]-'a']==NULL)
temp->idx[s[i]-'a']=create();
temp = temp->idx[s[i]-'a'];
(temp->cnt)++;
}
temp->end=1;
}
Runtime: The same as before O(m) where m is length of s.
Note: I made find method since anyway you need to traverse at most twice that path of the trie. One way is the mentioned at the beginning, a second one is to check duplicates (end property) when you have the node that represent s and if it is indeed a duplicated string then you traverse again s path fixing the extra +1 in cnt property.

How can I customize values for genes of chromosome?

I am trying to solve one job assignment problem using GeneticSharp. It is assigning gates to the trucks, and not all gates are suitable for the trucks.
Each chromosome is required to have gene values from a certain array of double values, corresponding to gene index (each gene index is equal to truck number). So, I'm trying to get a value randomly from that array and assign to gene in FloatingPointChromosome class, but this gives me an error of 'Object reference not set to an instance of an object. allowedStands was null'.
Could you, please, advise me how to solve it?
public FloatingPointChromosome(double[] minValue, double[] maxValue, int[] totalBits, int[] fractionDigits, double[] geneValues, double[][] allowedStands)
: base(totalBits.Sum())
{
m_minValue = minValue;
m_maxValue = maxValue;
m_totalBits = totalBits;
m_fractionDigits = fractionDigits;
// If values are not supplied, create random values
if (geneValues == null)
{
geneValues = new double[minValue.Length];
//var rnd = RandomizationProvider.Current;
var rnd = new Random();
for (int i = 0; i < geneValues.Length; i++)
{
int a = rnd.Next(allowedStands[i].Length);
geneValues[i] = allowedStands[i][a];
//I make here that it randomly selects from allowed gates array
}
}
m_originalValueStringRepresentation = String.Join(
"",
BinaryStringRepresentation.ToRepresentation(
geneValues,
totalBits,
fractionDigits));
CreateGenes();
}
I guess in the case of truck and gate assignment is better you create your own chromosome, take a look on TspChromosome to get an idea.
public TspChromosome(int numberOfCities) : base(numberOfCities)
{
m_numberOfCities = numberOfCities;
var citiesIndexes = RandomizationProvider.Current.GetUniqueInts(numberOfCities, 0, numberOfCities);
for (int i = 0; i < numberOfCities; i++)
{
ReplaceGene(i, new Gene(citiesIndexes[i]));
}
}
Using the same approach, you cities indexes are your gates indexes.

how much time will fibonacci series will take to compute?

i have created the recursive call tree by applying brute force technique but when i give this algorithm 100 values it takes trillion of years to compute..
what you guys suggest me to do that it runs fast by giving 100 values
here is what i have done so far
function fib(n) {
if (n =< 1) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
You can do it also with a loop:
int a = 1;
int b = 1;
for(int i = 2; i < 100; i++){
int temp = a + b;
a = b;
b = temp;
}
System.out.println("Fib 100 is: "+b);
The runtime is linear and avoids the overhead caused by the recursive calls.
EDIT: Please note that the result is wrong. Since Fib(100) is bigger than Integer.MAX_VALUE you have to use BigInteger or similar to get the correct output but the "logic" will stay the same.
You could have a "cache", where you save already computed Fibonacci numbers. Every time you try to compute
fib(n-1) /* or */ fib(n-2) ;
You would first look into your array of already computed numbers. If it's there, you save a whole lot of time.
So every time you do compute a fibonacci number, save it into your array or list, at the corresponding index.
function fib(n)
{
if (n =< 1)
{
return n;
}
if(fiboList[n] != defaultValue)
{
return fiboList[n];
}
else
{
int fibo = fib(n-1) + fib(n-2);
fiboList[n] = fibo;
return fibo;
}
}
You can also do it by dynamic programming:
def fibo(n):
dp = [0,1] + ([0]*n)
def dpfib(n):
return dp[n-1] + dp[n-2]
for i in range(2,n+2):
dp[i] = dpfib(i)
return dp[n]

questions about binary search tree

Show that every n-node binary search tree is not equally likely (assuming items are inserted in random order), and that balanced trees are more probable than straight-line trees.
How is it prove mathematical?
Number of possible tree configurations: see With ' N ' no of nodes, how many different Binary and Binary Search Trees possible?
Number of ways to get a single line, most imbalanced, deepest tree with n nodes: 2^(n-1)
Explanation:
2 ways to pick up first node (greatest or smallest)
X 2 ways to pick up second node (greatest or smallest among the n-1 remaining nodes
...
X 2 ways to pick up the (n-1)th node
X 1 way to pick up the last node
Number of ways to add n items to a binary tree in such a way that it is balanced:
Let g(n,m) denote the number of ways to merge two ordered lists by picking elements from one list or the other one at a time until both lists are empty. g(n,m) = g(n-1,m) + g(n,m-1) which happen to correspond to the numbers defined in the Pascal Triangle. That would give n+m chose n or n+m chose m = (n+m)! / n! (n+m-n)! = (n+m)!/(n! m!)
Example:
Number of ways to merge two ordered lists containing 2 elements each = 4!/(2! 2!) = 24 / 4 = 6
Assuming the two lists are as follows:
1 A
2 B
The six merging combinations are:
1 1 1 A A A
2 A A B 1 1
A 2 B 1 B 2
B B 2 2 2 B
Now, let f(n) denote the number of combinations in which n sorted elements can be added to a empty binary tree such that the binary tree is balanced. The only way to achieve that is to first add
the middle element if n is odd. That would be element ceiling(n/2). Each side would have n/2-1 elements.
either element n/2 or element n/2+1 if n is even. One side would have n/2-1 element, the other side n/2 elements and vice versa.
Once the middle element is selected, all elements to the left will always fall on the left subtree and all elements on the right will always fall on the right subtree. Assuming the elements on the right are ordered in such a way that the left subtree is balanced and the elements on the right are also ordered in such a way that the right subtree is balanced, merging the two lists in any way will always result in both subtree being balanced. That means that for each list of n and m elements that respectively fall on the left and right subtree such that both subtrees are balanced, there are (n+m)!/(n!m!) to merge them so as to achieve the same result.
That would give us (n+m)!/(n!m!) x f(n) x f(m)
We can now formulate this as follows:
Base cases:
f(1) = 1
f(2) = 2
General case:
f(n) = (n-1)!/[((n-1)/2)!]^2 x [f((n-1)/2)]^2 | n odd
f(n) = (n-1)!/((n/2-1)! x (n/2)!) x 2 x f(n/2-1) x f(n/2) | n even
Rest to transform this into a non recursive formula in terms of n. Maybe it would be easier to start with the easiest case where n = 2^m - 1 (i.e. removing a node and dividing by two will always give a whole number and will result in a completely balanced tree).
Note: I posted a related math question here: https://math.stackexchange.com/questions/460767/recurrent-relation-for-number-of-ways-to-get-a-balanced-n-binary-tree
Following is a C# console application that lists all the sequences in which nodes can be added to a binary tree so as to have it balanced (Run it here ):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AllBalancedTrees
{
class Program
{
static void Main(string[] args)
{
char[] nodes = { 'A', 'B', 'C', 'D', 'E' };
AllBalancedTrees<char> AllBalancedTrees = new AllBalancedTrees<char>();
foreach (char[] a in AllBalancedTrees.allBalancedTreeCombinations(nodes))
{
foreach (char c in a)
{
Console.Write(c + " ");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
class AllBalancedTrees<T>
{
public IEnumerable<T[]> allBalancedTreeCombinations(T[] nodes)
{
T[] result;
if (nodes.Length == 1)
{
yield return nodes;
}
else if (nodes.Length == 2)
{
yield return nodes;
T[] nodes2 = new T[2];
nodes2[0] = nodes[1];
nodes2[1] = nodes[0];
yield return nodes2;
}
else if (nodes.Length % 2 == 1)
{
int mid = (nodes.Length - 1) / 2;
T[] left = new T[mid];
T[] right = new T[mid];
Array.Copy(nodes, 0, left, 0, mid);
Array.Copy(nodes, mid + 1, right, 0, mid);
foreach (T[] l in allBalancedTreeCombinations(left))
{
foreach (T[] r in allBalancedTreeCombinations(right))
{
result = new T[nodes.Length];
result[0] = nodes[mid];
foreach (T[] a in allMergeCombinations(l, r))
{
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
}
else
{
int mid = (nodes.Length) / 2;
T[] left = new T[mid];
T[] right = new T[mid - 1];
Array.Copy(nodes, 0, left, 0, mid);
Array.Copy(nodes, mid + 1, right, 0, mid - 1);
foreach (T[] l in allBalancedTreeCombinations(left))
{
foreach (T[] r in allBalancedTreeCombinations(right))
{
result = new T[nodes.Length];
result[0] = nodes[mid];
foreach (T[] a in allMergeCombinations(l, r))
{
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
mid = nodes.Length / 2 - 1;
left = new T[mid];
right = new T[mid + 1];
Array.Copy(nodes, 0, left, 0, mid);
Array.Copy(nodes, mid + 1, right, 0, mid+1);
foreach (T[] l in allBalancedTreeCombinations(left))
{
foreach (T[] r in allBalancedTreeCombinations(right))
{
result = new T[nodes.Length];
result[0] = nodes[mid];
foreach (T[] a in allMergeCombinations(l, r))
{
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
}
}
public IEnumerable<T[]> allMergeCombinations(T[] firstArray, T[] secondArray)
{
if (firstArray.Length == 0)
{
yield return secondArray;
}
else if (secondArray.Length == 0)
{
yield return firstArray;
}
else
{
T[] result;
T[] firstMinusOne;
firstMinusOne = new T[firstArray.Length - 1];
Array.Copy(firstArray, 1, firstMinusOne, 0, firstMinusOne.Length);
foreach (T[] a in allMergeCombinations(firstMinusOne, secondArray))
{
result = new T[firstArray.Length + secondArray.Length];
result[0] = firstArray[0];
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
T[] secondMinusOne;
secondMinusOne = new T[secondArray.Length - 1];
Array.Copy(secondArray, 1, secondMinusOne, 0, secondMinusOne.Length);
foreach (T[] a in allMergeCombinations(firstArray, secondMinusOne))
{
result = new T[firstArray.Length + secondArray.Length];
result[0] = secondArray[0];
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
}
}
Every n-node binary search tree is not equally likely because, if items are inserted in random order, there is a much greater probability that the input will not be in strictly increasing or decreasing order. As long as the items are not in ascending or descending order, a straight-line tree is an impossibility.
For example, in a tree of four records with keys 1, 2, 3, and 4, there are 4! or 24 ways for these items to be ordered as input. Only two of these ways can result in a straight-line tree (4, 3, 2, 1 and 1, 2, 3, 4). In this case the probability of a straight-line tree is approximately 8.3%, whereas the probability of a (somewhat) balanced tree is 91.6%. Clearly, the odds are against the chances of getting a straight-line tree for a result.

Linear search to get the position to insert an item in the array

How to do linear I want to get the position for an item in the array to insert , I mean the index where I have to insert the data in the array. How can I achieve this by using Linear search only . Suggestions Please.
Linear search for example with a for loop:
int[] test = new int[1024];
// i assume you have something like this
int searchnumber = 17;
int foundindex = -1;
for(int i = 0; i < count, i++)
{
if (test[i] == 17)
{
foundindex = i;
break;
}
}
// now you have the found index in foundindex
If your array is sorted you could use a binary search, but since you asked for a linear search tghis should do the trick.
Find the nearest possible value and insert before or after it depending on your need
loop
{
int index = [arrResultRow indexOfObject:10];
[arrResultRow insertObject:object atIndex:index+1]
}