Get the path between two items in array - c#

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.

Related

Join element from array if the array element length is less than 5

I am trying to join the next array element together to single element from array if the element of the array is less than length 4. It should add to the next element index.
Another logic is, if the next consecutive array length is also less then 4 char then it joins the next array element also up to 3 times in total. I want to implement this. It's getting complex for me I am not understand this logic.
This is the code, here it has array on titleList, now we have to use the above logic in this array list.
#foreach (var title in randomtitle)
{
</span>#titleList.ElementAt(title)</span>
}
#code {
[Parameter]
public string theTitle { get; set; }
private string[] titleList = Array.Empty<string>();
protected override void OnParametersSet()
{
if (!string.IsNullOrEmpty(theTitle))
{
titleList = theTitle.Split(" ");
}
}
private Random random = new();
private IEnumerable<int> randomtitle =>
Enumerable.Range(0, titleList.Count() - 1) // { 0, 1, 2, 3 } generate sequence
.OrderBy(x => random.Next()) // { 3, 1, 0, 2 } random shuffle
.Take(2) // { 3, 1 } pick two
.ToList();
}
I think you are looking for a method that does following:
take a collection of strings(like a string[])
iterate each string and check if it's length is greater than or equal 4
if so, everything is fine, take it as it is
if not, append the next to the current string and check their length afterwards
if they are still not greater than or equal 4 append the next one, but max 3 times
Then this should work (not tested well though):
Demo: https://dotnetfiddle.net/2uHREv
static string[] MergeItems(IList<string> all, int minLength, int maxGroupCount)
{
List<string> list = new List<string>(all.Count);
for(int i = 0; i < all.Count; i++)
{
string current = all[i];
if(i == all.Count - 1)
{
list.Add(current);
break;
}
if (current.Length < minLength)
{
for (int ii = 1; ii < maxGroupCount && i + ii < all.Count; ii++)
{
int nextIndex = i + ii;
string next = all[nextIndex];
current = current + next;
if (current.Length >= minLength || ii+1 == maxGroupCount)
{
list.Add(current);
i = nextIndex;
break;
}
}
}
else
{
list.Add(current);
}
}
return list.ToArray();
}

c# finding even or odd numbers

Question: You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.
Examples
[2, 4, 0, 100, 4, 11, 2602, 36]
Should return: 11 (the only odd number)
[160, 3, 1719, 19, 11, 13, -21]
Should return: 160 (the only even number)
Problem: I can find the target number. It is "6" in this instance. But when i try to write it, it is written 3 times. I did not understand why it is not written once.
namespace sayitoplamları
{
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] {1,3,5,6};
int even = 0;
int odd = 0;
foreach (var num in integers)
{
if (num%2==0)
{
even += 1;
}
else
{
odd += 1;
}
if (even>1)
{
foreach (var item in integers)
{
if (item%2!=0)
{
Console.WriteLine(item);
}
}
}
else if (odd>1)
{
foreach (var item in integers)
{
if (item%2==0)
{
Console.WriteLine(item);
}
}
}
}
}
}
}```
Since we are doing this assignment for a good grade :)
We really don't need to count both odd and even elements and can just count odd once as it more convenient - just add up all remainders ( odd % 2 = 1, even % 2 = 0). If we would need number of even elements it would be array.Length - countOdd.
int countOdd = 0;
for (int i = 0; i < array.Length; i++) // or foreach
{
countOdd += array[i] % 2;
}
If you feel that trick with counting is too complicated and only needed for A+ mark on the assignment than variant of your original code is fine:
int countOdd = 0;
foreach (int element in array)
{
if (element % 2 == 1)
countOdd ++; // which is exactly countOdd += 1, just shorter.
}
Now for the second part - finding the outlier. We don't even need to know if it is Odd or Even but rather just reminder from "% 2". We now know how many odd element - which could be either 1 (than desired remainder is 1 - we are looking for odd element) or more than one (then desired remainder is 0 as we are looking for even one).
int desiredRemainder = countOdd == 1 ? 1 : 0;
Now all its left is to check which element has desired remainder and return from our method:
foreach (int element in array)
{
if (element % 2 == desiredRemainder)
{
return element;
}
}
Please note that assignment asks for "return" and not "print". Printing the value does not allow it to be used by the caller of the method unlike returning it. Using early return also saves some time to iterate the rest of array.
Complete code:
int FindOutlier(int[] array)
{
int desiredReminder = array.Sum(x => x % 2) == 1 ? 1 : 0;
return array.First(x => x % 2 == desiredReminder);
}
Alternative solution would be to iterate array only once - since we need to return first odd or first even number as soon as we figure out which one repeats similar how your tried with nested foreach. Notes since we are guaranteed that outlier present and is only one we don't need to try to remember first number - just current is ok.
int FindOutlier(int[] array)
{
int? odd = null; // you can use separate int + bool instead
int? even = null;
int countOdd = 0;
int countEven = 0;
foreach (int element in array)
{
bool isEven = element % 2 == 0;
if (isEven)
{
countEven++;
even = element;
}
else
{
countOdd++;
odd = element;
}
if (countEven > 1 && odd.HasValue)
return odd.Value;
if (countOdd > 1 && even.HasValue)
return even.Value;
}
throw new Exception("Value must be found before");
}
And if you ok to always iterate whole list code will be simple as again we'd need to only keep track of count of odd numbers (or even, just one kind) and return would not need to check if we found the value yet as we know that both type of numbers are present in the list:
int FindOutlier(int[] array)
{
int odd = 0;
int even = 0;
int countEven = 0;
foreach (int element in array)
{
if (element % 2 == 0)
{
countEven++;
even= element;
}
else
{
odd = element;
}
}
return countEven > 1 ? odd : even;
}
You are mixing everything into a single algorithm. In most cases it's a better idea to have separate steps. In your case, the steps could be:
Count odds and evens
Find the outlier
Print the result
That way you can make sure that the output does not interfere with the loops.
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] {1,3,5,6};
int even = 0;
int odd = 0;
// Count odds and evens
foreach (var num in integers)
{
if (num%2==0)
{
even += 1;
}
else
{
odd += 1;
}
}
// Find the outlier
var outlier = 0;
foreach (var item in integers)
{
if (even == 1 && item%2==0)
{
outlier = item;
break;
}
if (odd == 1 && item%2!=0)
{
outlier = item;
break;
}
}
// Print the result
Console.WriteLine(outlier);
}
}
You could even make this separate methods. It also makes sense due to SoC (separation of concerns) and if you want to achieve testability (unit tests).
You want a method anyway and use the return statement, as mentioned in the assignment
Write a method that takes the array as an argument and returns this "outlier" N.
Maybe you want to check the following code, which uses separate methods:
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] { 1, 3, 5, 6 };
var outlier = FindOutlier(integers);
Console.WriteLine(outlier);
}
private static int FindOutlier(int[] integers)
{
if (integers.Length < 3) throw new ArgumentException("Need at least 3 elements.");
bool isEvenOutlier = IsEvenOutlier(integers);
var outlier = FindOutlier(integers, isEvenOutlier ? 0:1);
return outlier;
}
static bool IsEvenOutlier(int[] integers)
{
// Count odds and evens
int even = 0;
int odd = 0;
foreach (var num in integers)
{
if (num % 2 == 0)
{
even += 1;
}
else
{
odd += 1;
}
}
// Check which one occurs only once
if (even == 1) return true;
if (odd == 1) return false;
throw new ArgumentException("No outlier in data.", nameof(integers));
}
private static int FindOutlier(int[] integers, int remainder)
{
foreach (var item in integers)
{
if (item % 2 == remainder)
{
return item;
}
}
throw new ArgumentException("No outlier in argument.", nameof(integers));
}
}
The reason it is printing '6' 3 times is because you iterate over the inetegers inside a loop where you iterate over the integers. Once with num and again with item.
Consider what happens when you run it against [1,3,5,6].
num=1, you get odd=1 and even=0. Neither of the if conditions are true so we move to the next iteration.
num=3, you get odd=2 and even=0. odd > 1 so we iterate over the integers (with item) again and print '6' when item=6.
num=5, you get odd=3 and even=0. Again, this will print '6' when item=6.
num=6, you get odd=3 and even=1. Even though we incremented the even count, we still have odd > 3 so will print '6' when item=6.
It is best to iterate over the values once and store the last even and last odd numbers along with the count (it is more performant as well).
You can then print the last odd number if even > 0 (as there will only be one odd number, which will be the last one) or the last even number if odd > 0.
I.e.
namespace sayitoplamları
{
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] { 1, 3, 5, 6 };
int even = 0;
int? lastEven = null;
int odd = 0;
int? lastOdd = null;
foreach (var num in integers)
{
if (num % 2 == 0)
{
even += 1;
lastEven = num;
}
else
{
odd += 1;
lastOdd = num;
}
}
if (even > 1)
{
Console.WriteLine(lastOdd);
}
else if (odd > 1)
{
Console.WriteLine(lastEven);
}
}
}
}
because you didn't close the the first foreach loop before printing...
namespace sayitoplamları
{
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] {1,3,5,6};
int even = 0;
int odd = 0;
foreach (var num in integers)
{
if (num%2==0)
{
even += 1;
}
else
{
odd += 1;
}//you need to close it here
if (even>1)
{
foreach (var item in integers)
{
if (item%2!=0)
{
Console.WriteLine(item);
}
}
}
else if (odd>1)
{
foreach (var item in integers)
{
if (item%2==0)
{
Console.WriteLine(item);
}
}
}
}
}//not here
}
}

c# find max value recursive (fastest)

I'm out of ideas on this one. Tried originally myself and then copied from SO and google, which worked on all cases except one, however still didn't find a recursive algorithm that is fast enough for that particular test case in my assignment :/
In any case, why this:
public static int FindMaximum(int[] array)
{
if (array is null)
{
throw new ArgumentNullException(nameof(array));
}
if (array.Length == 0)
{
throw new ArgumentException(null);
}
return FindMaxRec(array, array.Length);
}
public static int FindMaxRec(int[] arr, int n)
{
if (n == 1)
{
return arr[0];
}
return Math.Max(arr[n - 1], FindMaxRec(arr, n - 1));
}
doesn't work with this TestCase?:
[Test]
[Order(0)]
[Timeout(5_000)]
public void FindMaximum_TestForLargeArray()
{
int expected = this.max;
int actual = FindMaximum(this.array);
Assert.AreEqual(expected, actual);
}
EDIT 1:
This works fine though, but I need recursive:
public static int FindMaximum(int[] array)
{
if (array is null)
{
throw new ArgumentNullException(nameof(array));
}
if (array.Length == 0)
{
throw new ArgumentException(null);
}
int maxValue = int.MinValue;
for (int i = 0; i < array.Length; i++)
{
if (array[i] > maxValue)
{
maxValue = array[i];
}
}
return maxValue;
}
You can try splitting array in two:
public static int FindMaximum(int[] array) {
if (null == array)
throw new ArgumentNullException(nameof(array));
if (array.Length <= 0)
throw new ArgumentException("Empty array is not allowed.", nameof(array));
return FindMaxRec(array, 0, array.Length - 1);
}
private static int FindMaxRec(int[] array, int from, int to) {
if (to < from)
throw new ArgumentOutOfRangeException(nameof(to));
if (to <= from + 1)
return Math.Max(array[from], array[to]);
return Math.Max(FindMaxRec(array, from, (from + to) / 2),
FindMaxRec(array, (from + to) / 2 + 1, to));
}
Demo:
Random random = new Random(123);
int[] data = Enumerable
.Range(0, 10_000_000)
.Select(_ => random.Next(1_000_000_000))
.ToArray();
Stopwatch sw = new Stopwatch();
sw.Start();
int max = FindMaximum(data);
sw.Stop();
Console.WriteLine($"max = {max}");
Console.WriteLine($"time = {sw.ElapsedMilliseconds}");
Outcome:
max = 999999635
time = 100
An easy way to turn a simple linear algorithm into a recursive one is to make use of the enumerator of the array.
public static int FindMax(int[] values)
{
using var enumerator = values.GetEnumerator();
return FindMaxRecursively(enumerator, int.MinValue);
}
private static T FindMaxRecursively<T>(IEnumerator<T> enumerator, T currentMax) where T : IComparable
{
if (!enumerator.MoveNext()) return currentMax;
var currentValue = enumerator.Current;
if (currentValue.CompareTo(currentMax) > 0) currentMax = currentValue;
return FindMaxRecursively(enumerator, currentMax);
}
This passes your test case and uses recursion.
Edit: Here is a more beginner friendly version of the above, with comments to explain what it is doing:
public static int FindMax(IEnumerable<int> values)
{
using var enumerator = values.GetEnumerator();//the using statement disposes the enumerator when we are done
//disposing the enumerator is important because we want to reset the index back to zero for the next time someone enumerates the array
return FindMaxRecursively(enumerator, int.MinValue);
}
private static int FindMaxRecursively(IEnumerator<int> enumerator, int currentMax)
{
if (!enumerator.MoveNext()) //move to the next item in the array. If there are no more items in the array MoveNext() returns false
return currentMax; //if there are no more items in the array return the current maximum value
var currentValue = enumerator.Current;//this is the value in the array at the current index
if (currentValue > currentMax) currentMax = currentValue;//if it's larger than the current maximum update the maximum
return FindMaxRecursively(enumerator, currentMax);//continue on to the next value, making sure to pass the current maximum
}
Something that might help understand this is that the IEnumerator is what enables foreach loops. Under the hood, foreach loops are just repeatedly calling MoveNext on an item that has an IEnumerator. Here is some more info on that topic.
public static int findMax(int[] a, int index) {
if (index > 0) {
return Math.max(a[index], findMax(a, index-1))
} else {
return a[0];
}
}

Function to determine combinations of values that combined are less than a threshold value

I am trying to develop an optimization function that will determine which elements in list of doubles when added together will be less than a specified threshold values. The elements can be used multiple times.
For example if my list of elements is
{1,3,7,10}
and my threshold is 20 I would expect my result to be
1
3
7
10
10, 10
10, 7
10, 7, 3
10,7,1
10,7,1,1
10,7,1,1,1
7,7
7,7,3
7,7,1
7,7,1,1
7,7,1,1,1
...
I expect that the answer to this question will probably be a recursive call and probably could be found in a textbook, but I don't know how to properly phrase the question to find the answer. Help from this group of experts would be appreciated.
This program works, and seems to be the simplest solution. All results are sorted ascending.
private static final HashSet<ArrayList<Double>> lists =
new HashSet<ArrayList<Double>>(); // all of the combinations generated
private static final double[] elements = {10, 7, 3, 1};
public static void main(String[] args) {
combine(20, new ArrayList<Double>());
for (ArrayList<Double> set : lists) {
System.out.println(set);
}
}
private static void combine(final double limit, ArrayList<Double> stack) {
// iterates through the elements that fit in the threshold
for (double item : elements) {
if (item < limit) {
final ArrayList<Double> nextStack = new ArrayList<Double>(stack);
nextStack.add(item);
// a sort is necessary to let the HashSet de-dup properly
Collections.sort(nextStack);
lists.add(nextStack);
combine(limit - item, nextStack);
}
}
}
This type of combinatoric problem, though, generates many results. If you are more concerned with performance than code readability and simplicity, I can optimize further.
c#:
static void Main(string[] args)
{
Run();
}
static public void Run()
{
Combine(20, new List<Double>());
foreach (List<Double> set in lists)
{
Debug.Print(set.ToString());
}
}
private static HashSet<List<Double>> lists =
new HashSet<List<Double>>(); // all of the combinations generated
private static double[] elements = { 10, 7, 3, 1 };
private static void Combine(double limit, List<Double> stack)
{
// iterates through the elements that fit in the threshold
foreach (double item in elements)
{
if (item < limit)
{
List<Double> nextStack = new List<Double>(stack);
nextStack.Add(item);
// a sort is necessary to let the HashSet de-dup properly
nextStack.Sort();
lists.Add(nextStack);
Combine(limit - item, nextStack);
}
}
}
I'm not sure if the Sort() is needed for detecting correctly duplicate entries but this code should work:
private List<int[]> CombinedElementsInArrayLessThanValue(int[] foo, int value)
{
List<int[]> list = new List<int[]>();
for (int i = 0; i < foo.Length; i++)
{
List<int> start = new List<int>();
start.Add(foo[i]);
start.Sort();
int[] clone = start.ToArray();
if (start.Sum() < value && !list.Contains(clone))
{
list.Add(clone);
CombinedElementsInArrayLessThanValue(foo, value, start, list);
}
}
return list;
}
private void CombinedElementsInArrayLessThanValue(int[] foo, int value, List<int> partial, List<int[]> accumulate_result)
{
for (int i = 0; i < foo.Length; i++)
{
List<int> clone = new List<int>(partial);
clone.Add(foo[i]);
clone.Sort();
int[] array = clone.ToArray();
if (clone.Sum() < value && !accumulate_result.Contains(array))
{
accumulate_result.Add(array);
CombinedElementsInArrayLessThanValue(foo, value, clone, accumulate_result);
}
}
}
Process one item in the list at a time, and let the recursion handle one item completely in order to shorten the "depth" of the recursion.
public static List<int[]> Combine(int[] elements, int maxValue)
{
LinkedList<int[]> result = new LinkedList<int[]>();
List<int> listElements = new List<int>(elements);
listElements.Sort();
Combine(listElements.ToArray(), maxValue, new int[0], result);
return result.ToList();
}
private static void Combine(int[] elements, int maxValue, int[] stack, LinkedList<int[]> result)
{
if(elements.Length > 0 && maxValue >= elements[0])
{
var newElements = elements.Skip(1).ToArray();
for (int i = maxValue / elements[0]; i > 0; i--)
{
result.AddLast(stack.Concat(Enumerable.Repeat(elements[0], i)).ToArray());
Combine(newElements, maxValue - i*elements[0], result.Last(), result);
}
Combine(newElements, maxValue, stack, result);
}
}

How to create a binary tree

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);
}
}

Categories

Resources