I’m working on a binary search tree console application, specifically, a method to list the shortest path between two target nodes. My approach is to
1) Create an ArrayList of the values of each target node in the tree from the root node to the target (one ArrayList for each path)
2) Compare the two ArrayLists, removing all duplicates except the last one (which would represent where the two paths branch
3) combine the two remaining ArrayLists into a single array and print to console with a for loop
This is the method I’m working with. The problem I’m having is that I’m never entering the block that reads “if (list1[n] == list2[n])”, even though the ArrayLists are printing out with the values
Contents of _pathArrayList1: 5, 7, 9
Contents of _pathArrayList2: 5, 7, 9, 10, 12, 11
I tried typcasting, but that didn’t help.
array<T>^ removeDuplicates(ArrayList^ list1, ArrayList^ list2)
{
int forLoopCount;
int i; // for loop iterator for this method
Console::WriteLine(L"Contents of _pathArrayList1: ");
for (i = 0; i < list1->Count; i++)
Console::WriteLine(list1[i]);
Console::WriteLine(L"Contents of _pathArrayList2");
for (i = 0; i < list2->Count; i++)
Console::WriteLine(list2[i]);
// find out which array is the shortest; we need to use the shorter of the two
if (list1->Count - list2->Count < 0)
forLoopCount = list1->Count;
else
forLoopCount = list2->Count;
Console::WriteLine("Value of forLoopCopunt is " + forLoopCount);
array<T>^ combineArray = gcnew array<T>(forLoopCount);
for (int n = 0; n < forLoopCount; n++)
{
Console::WriteLine(L"List1[n] = " + list1[n]);
Console::WriteLine(L"list2[n] = " + list2[n]);
if (list1[n] == list2[n]) // never entering this block of code
{
if (list2[n+1] == list1[n+1])
{
Console::WriteLine(L"Removing " + list1[n] + " and " + list2[n]);
list1->RemoveAt(n);
list2->RemoveAt(n);
n --;
}
else
{
Console::WriteLine(L"Deleting " + list1[n]);
list1->RemoveAt(n);
//_pathArrayList1->Reverse();
return combineArray = combineArrays(_pathArrayList1, _pathArrayList2);
}
}
}
return combineArray = combineArrays(_pathArrayList1, _pathArrayList2);
}
Please clarify “I tried typcasting, but that didn’t help.”.
ArrayListdoes not use generics, so it deals with everything as Objects. Even if the two objects are ints, when they’re typed as Object,==won’t compare the integer values as you expect.If you switch out your
ArrayListforList<int>, then==will work as you expect, with the added benefits of type-safety.Other Notes:
forLoopCount. If other people have to stop and think about it to figure out if the code is correct, for something that simple, use the function.list2[n+1] == list1[n+1], make sure there’s an extra item in both lists. In your example data (5-7-9 and 5-7-9-10-12-11), this will give you an exception whenlist1[n]is the 9.gcnew array<T>(forLoopCount), or evencombineArrayentirely. That object is getting thrown away when you assign the return value of combineArrays.Edit
If the objects in the passed lists are the items themselves (not their node addresses, or something else that’s always an
int), then I’d recommend addingwhere T : IEquatable<T>to the generic definition. That gives you an Equals(T) method, and you can use that instead of==, which isn’t defined for all types. (If you implement this on your types, just be sure to implement all three methods Equals(T), Equals(object), and GetHashCode(), so that everything’s consistent.)To help with building the search tree in the first place, you may find
IComparable<T>useful. Use the CompareTo method instead of the comparison operators (e.g.,<).