BinaryTree Insert Method - c++

For class I have to create a binaryTree and I can't seem to get the insert method to work properly.
Expected results:
first: tree is not empty
no of nodes = 15
height of tree = 5
The elements of 'first' in inorder:
-11 8 -3 12 -1 -9 -5 2 16 10 6 -13 4 14 -7
The elements of 'first' in preorder:
2 -1 -3 8 -11 12 -5 -9 4 6 10 16 -13 -7 14
The elements of 'first' in postorder:
-11 8 12 -3 -9 -5 -1 16 10 -13 6 14 -7 4 2
second: tree is not empty
no of nodes = 9
height of tree = 4
The elements of 'second' in inorder:
7 3.25 0.75 -7.75 -0.5 -11.5 4.5 -4 8.25
The elements of 'second' in preorder:
-0.5 0.75 3.25 7 -7.75 -4 4.5 -11.5 8.25
The elements of 'second' in postorder:
7 3.25 -7.75 0.75 -11.5 4.5 8.25 -4 -0.5
third: tree is not empty
no of nodes = 7
height of tree = 4
The elements of 'third' in inorder:
objects. list is string This of a
The elements of 'third' in preorder:
This is list objects. string a of
The elements of 'third' in postorder:
objects. list string is of a This
My Results:
first: tree is not empty
no of nodes = 15
height of tree = 4
The elements of 'first' in inorder:
-9 -5 4 16 -1 -13 10 -7 2 14 8 6 -3 -11 12
The elements of 'first' in preorder:
2 -1 4 -5 -9 16 -7 10 -13 -3 6 8 14 12 -11
The elements of 'first' in postorder:
-9 -5 16 4 -13 10 -7 -1 14 8 6 -11 12 -3 2
second: tree is not empty
no of nodes = 9
height of tree = 3
The elements of 'second' in inorder:
-7.75 -4 0.75 -11.5 8.25 -0.5 7 4.5 3.25
The elements of 'second' in preorder:
-0.5 0.75 -4 -7.75 8.25 -11.5 3.25 4.5 7
The elements of 'second' in postorder:
-7.75 -4 -11.5 8.25 0.75 7 4.5 3.25 -0.5
third: tree is not empty
no of nodes = 7
height of tree = 3
The elements of 'third' in inorder:
string a is This objects. of list
The elements of 'third' in preorder:
This is a string list of objects.
The elements of 'third' in postorder:
string a is objects. of list This
Code:
template <class T>
void binTree<T>::insert(binTreeNode < T >*& node, const T& data) {
if(node == NULL) {
root = new binTreeNode<T>(data, NULL, NULL);
return;
}
binTreeNode<T>* ptr1 = node;
binTreeNode<T>* ptr2 = node;
bool placeRight = 0;
while(ptr1 != NULL) {
ptr2 = ptr1;
if(height(ptr1->left) > height(ptr1->right)) {
placeRight = true;
ptr1 = ptr1->right;
} else if (height(ptr1->right) > height(ptr1->left)) {
placeRight = false;
ptr1 = ptr1->left;
} else {
placeRight = false;
ptr1 = ptr1->left;
}
}
if(placeRight) {
ptr2->right = new binTreeNode<T>(data, NULL, NULL);
} else {
ptr2->left = new binTreeNode<T>(data, NULL, NULL);
}
}
Driver Program:
const vector<int> A { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15 };
const vector<float> B { 0.5, 1.75, -3, 4.25, 5.50, -6.75, 8, 9.25, -10.5 };
const vector<string> C { "This", "is", "a", "list", "of", "string", "objects." };
int main() {
binTree<int> intTree = binTree<int>();
binTree<float> floatTree = binTree<float>();
binTree<string> strTree = binTree<string>();
for (std::vector<int>::const_iterator it = A.begin() ; it != A.end(); ++it) {
intTree.insert(*it);
}
intTree.preorder(increase);
cout << "first: ";
header(intTree);
inorder(intTree, "first");
preorder(intTree, "first");
postOrder(intTree, "first");
}
Functions to display results: (should be correct)
template <class T>
void binTree<T>::inorder(binTreeNode < T >* node, void (*f)(T&))
{
if (node == NULL) {
return;
}
inorder(node->left,f);
f(node->data);
inorder(node->right,f);
}
template <class T>
void binTree<T>::preorder(binTreeNode < T >* node, void(*f)(T&))
{
if (node == NULL) {
return;
}
f(node->data);
preorder(node->left, f);
preorder(node->right, f);
}
template <class T>
void binTree<T>::postorder(binTreeNode < T >* node, void(*f)(T&))
{
if (node == NULL) {
return;
}
postorder(node->left, f);
postorder(node->right, f);
f(node->data);
}
template <class T>
int binTree<T>::height(binTreeNode <T>* node) const {
if (node == NULL || ((node->left == NULL) && (node->right == NULL))) {
return 0;
}
int leftSide = height(node->left);
int rightSide = height(node->right);
if (leftSide > rightSide) {
return leftSide + 1;
} else {
return rightSide + 1;
}
}

Your bug is in your height method. If you have a node which is not null but has no children, you are returning zero. You should be returning 1.
Change this condition in your height method from:
if (node == NULL || ((node->left == NULL) && (node->right == NULL))) {
return 0;
}
to:
if (node == NULL) {
return 0;
}

It appears the sign of your vector A is backwards. You have 1,-2,3,-4,... but the correct solution has -1,2,-3,4,.... Similarly, you B is
const vector<float> B { 0.5, 1.75, -3, 4.25, 5.50, -6.75, 8, 9.25, -10.5 };
Comparing this with the elements you say we are expecting:
7, 3.25, 0.75, -7.75, -0.5, -11.5, 4.5, -4, 8.25
These don't look even close to identical.
Transcription error somewhere?

What is your height() function ?
I think you misunderstand the definition of the BST:
A. the value of the left child is smaller than the value of root node.
B. the value of the right child is bigger than the value of root node.
C. his left child tree and right child tree are also a BST.
But through your code here:
while(ptr1 != NULL) {
ptr2 = ptr1;
if(height(ptr1->left) > height(ptr1->right)) {
placeRight = true;
ptr1 = ptr1->right;
} else if (height(ptr1->right) > height(ptr1->left)) {
placeRight = false;
ptr1 = ptr1->left;
} else {
placeRight = false;
ptr1 = ptr1->left;
}
}
you just compare the height of your node instead of comparing the real value of the node.

Related

how would i find the length? i have 8 tubes and 11 nodes

So i have 11 tubes and 8 nodes.
The lenght is the distance from node 1 to node 2.
8 //nodes
11 //tubes
0 0 -50 //node_x, node_y, flow
1000 0 -50 //node_x, node_y, flow
2000 0 0 //node_x, node_y, flow
0 500 0 //node_x, node_y, flow
500 500 0 //node_x, node_y, flow // NODES
0 1000 -50 //node_x, node_y, flow
1000 1000 0 //node_x, node_y, flow
2000 1000 150 //node_x, node_y, flow
1 2 0.5 //Node_1, Node_2, Diameter
2 3 0.5 //Node_1, Node_2, Diameter
1 4 0.5 //Node_1, Node_2, Diameter
4 5 0.5 //Node_1, Node_2, Diameter
2 5 0.5 //Node_1, Node_2, Diameter
2 8 0.5 //Node_1, Node_2, Diameter // TUBES
3 8 0.5 //Node_1, Node_2, Diameter
4 6 0.5 //Node_1, Node_2, Diameter
6 7 0.5 //Node_1, Node_2, Diameter
5 7 0.5 //Node_1, Node_2, Diameter
7 8 0.5 //Node_1, Node_2, Diameter
As seen the text file above we have 8 data for nodes with node x,y,flow values and 11 data for tubes with its node 1,2 id and diameter.
which means the first data of tube which is id 1 and id 2 = to 0 0 -50 and 1000 0 -50 so the length is 1000. As shown in picture we need the x value here so x is returned in the c++.
My code right now is hard coded which is like this:
for (int i = 0; i < 11; i++)
{
//1
if (node1_[i].id() == 0 && node2_[i].id() == 1)
{
return node2_->x();
}
//2
if (node1_[i].id() == 1 && node2_[i].id() == 2)
{
return node1_->x();
}
//3
if (node1_[i].id() == 0 && node2_[i].id() == 3)
{
return node2_->y();
}
//4
if (node1_[i].id() == 3 && node2_[i].id() == 4)
{
return node2_->x();
}
//5
if (node1_[i].id() == 1 && node2_[i].id() == 4)
{
return std::sqrt((node2_->x()) * (node2_->x()) + (node2_->y()) * (node2_->y()));
}
//6
if (node1_[i].id() == 1 && node2_[i].id() == 7)
{
return std::sqrt((node1_->x()) * (node1_->x()) + (node2_->y()) * (node2_->y()));
}
//7
if (node1_[i].id() == 2 && node2_[i].id() == 7)
{
return node2_->y();
}
//8
if (node1_[i].id() == 3 && node2_[i].id() == 5)
{
return node1_->y();
}
//9
if (node1_[i].id() == 5 && node2_[i].id() == 6)
{
return node2_->x();
}
//10
if (node1_[i].id() == 4 && node2_[i].id() == 6)
{
return std::sqrt((node1_->x()) * (node1_->y()) + (node1_->x()) * (node1_->y()));
}
//11
if (node1_[i].id() == 6 && node2_[i].id() == 7)
{
return node1_->x();
}
}
How can i remove the manually written ids and make it data driven so it knows which id to pick itself
length[0] = 1000
length[1] = 1000
length[2] = 500
length[3] = 500
length[4] = 707.107
length[5] = 1414.21
length[6] = 1000
length[7] = 500
length[8] = 1000
length[9] = 707.107
length[10] = 1000
these are values which i am getting which are correct. but i would like to change the way i am doing it. change the hard coded method to a data driven way.
To "generalize" your calculations you need a "generalized" function which calculates based on the amount of nodes connected to a tube.
This You have to find yourself.
After reading in the data, what is needed can be calculated.
Here is an idea for reading the data:
Define class'es for Tube's and Node's.
Use a std::vector to contain them (std::vector<Tube> tubes; and std::vector<Node> nodes;
tubes should be contained inside the Node class
Read in all the tubes and nodes.
While reading tubes assign the lower numbered node number as the location of the tube
loop over the nodes and calculate using it's tubes using the generalized function

Construct Binary Tree from Parent Array test case failing

Link of the question-[Link][1]
Basically we are given an array of integers and it's size. Question is to construct a binary tree from it. Each index corresponds to data stored in a node, and the value of that index is the data of the parent. Value of the root node index would always be -1 as there is no parent for root. The Output will be the sorted level order traversal of the tree.
Now my approach is that I parse the array from 1 to n(not the 0th element/root node), and for each element, I get it's parent using the first function, and insert the child accordingly. But one particular test case is failing. Maybe the website's own output is not correct. I will post everything below:-
Example test case-
Size of array-7
Elements- -1 0 0 1 1 3 5
Output- 0 1 2 3 4 5 6
Particular test case(which is my doubt)-
Size of array- 42
Elements-
3 19 1 41 35 29 27 11 17 23 9 15 33 13 39 23 19 25 21 1 33 15 31 21 5 7 37 29 7 11 31 39 -1 27 3 9 25 17 13 41 37 35
Website's output- 32
My output - 0
Functions
void getParent(Node* root, int val, Node* &main)
{
if(root==NULL) return;
if(root->data==val){
main=root;
return;
}
getParent(root->left,val,main);
getParent(root->right,val,main);
}
Node *createTree(int parent[], int n)
{
if(n==0) return NULL;
Node * root=new Node(0);
for(int i=1;i<n;i++)
{
Node* main=NULL;
getParent(root,parent[i],main);
//main has the parent
Node* child=new Node(i);
if(main==NULL) break;
if(main->left==NULL)
{
main->left=child;
}
else if(main->right==NULL)
{
main->right=child;
}
}
return root;
}
[1]: https://www.geeksforgeeks.org/construct-a-binary-tree-from-parent-array-representation/
[2]: https://i.stack.imgur.com/0fRmn.png
Not sure what you are doing with your getParent method. Also you are initiating a root node with value 0 and not doing anywith it in the loop and then finally you return the root. I suspect your root will always have a value 0.
The solution is very simple actually. You initialize an array of nodes with each node's value as the index of the array. For example for an array of size 5, you create an array of 5 nodes with each node having a value of the index at which it is located.
Then next step is go through the parent array and see if the node located at parent[i] has either left or right "available", if yes assign the node accordingly.
the code is :
Node* createTree(int parent[], int n) {
Node** nodes = new Node*[n];
for ( int i = 0; i < n; i++ )
nodes[i] = new Node(i);
int rootIndex = 0;
for ( int i = 0; i < n; i++ ) {
if ( parent[i] == -1 ) {
rootIndex = i;
} else {
if ( nodes[parent[i]] -> left == NULL ) {
nodes[parent[i]] -> left = nodes[i];
} else if ( nodes[parent[i]] -> right == NULL ) {
nodes[parent[i]] -> right = nodes[i];
}
}
}
return nodes[rootIndex];
}

Breadth First Search fails to find destination that does exist

So I have been working on a Breadth First Search to get a path given a starting and ending node. However in some cases it seems to fail and not get the path, which I know is possible since a Depth First Search and visual inspection shows that it should exist.
I have an Adjacency Matrix:
1 2 3 4 5 6 7 8
1 0 20 25 20 0 0 0 0
2 20 0 5 0 30 0 0 0
3 25 5 0 13 8 21 0 0
4 20 0 13 0 0 17 0 0
5 0 30 8 0 0 33 0 0
6 0 0 21 17 33 0 0 0
7 0 0 0 0 0 0 0 10
8 0 0 0 0 0 0 10 0
Which has a graph as follows:
This is my function:
void Network::BFS(int src, int dest, vector<bool>& visited, vector<int>& path) {
// The Queue is the core for the BFS.
queue<int> Queue;
// Mark current node as visited.
visited[src] = true;
Queue.push(src);
// While queue is not empty.
while (!Queue.empty()) {
// Add node to path.
// Check if we have found the destination yet or not, if we have we do one last push to path and we're done!
if (Queue.front() == dest) {
return;
}
int top = Queue.front();
path.push_back(Queue.front());
// Pop off front.
Queue.pop();
// Iterate and process all none visited nodes.
for (int node = 0; node < amountOfNodes; node++) {
// Check if it is not visited already.
if (visited[node] == false && (adjMatrix[node * amountOfNodes + src] != 0)) {
Queue.push(node); // Add to end.
visited[node] = true;
}
}
}
}
Sample input and output:
(6, 3) -> Path is: 6
(1, 5) -> Path is: 1 2 3 4
As you can see, it does not compute the path properly at all. Where is my algorithm going wrong here, and how do I fix it?
BFS involves visiting adjacent nodes in a FIFO fashion. Once you reach a node, you put into the queue all its neighbours, unless they were already visited.
First off, there's a typo where you iterate over adjacent nodes. You want to traverse the top column, not the src one:
adjMatrix[node * amountOfNodes + top] != 0
// ~~^
Secondly, your current path implementation stores the visit order of nodes, not a path from the source to its destination. For the latter, you need to store the parent of each node, so that the final path can be restored by going from a child (destination) to its parent, grandparent, great-grandparent, ..., etc.
std::vector<int> parent(amountOfNodes, -1);
//...
if (visited[node] == false && (adjMatrix[node * amountOfNodes + top] != 0))
{
Queue.push(node); // Add to end.
visited[node] = true;
parent[node] = top;
}
Restoring the path is straightforward:
int u = dest;
do
{
std::cout << u << " ";
u = parent[u];
}
while (u != -1);
DEMO

DFS on undirected graph

I have an exercise for university where I have to write a DFS algorithm to run on an undirected graph. I also have to make the program sum the values of all nodes show the order in which the nodes were visited.
Here is the given structure:
#include <iostream>
#include <cassert>
using namespace std;
struct node {
// DATA STRUCTURE NODES
};
int dfs_sum(/* FUNCTION ARGUMENTS */) {
// DEPTH FIRST SEARCH ALGORITHM
}
void node_init(/* FUNCTION ARGUMENTS */) {
// INITIALIZATION OF NODE WITH LABEL "value" AND NEIGHBOR "num_adjacent"
}
void edge_init(/* FUNCTION ARGUMENTS */) {
// INITIALIZATION OF EDGE BETWEEN TWO NODES
}
void node_delete(/* FUNCTION ARGUMENTS */) {
// DE-ALLOCATE MEMORY THAT WAS ALLOCATED IN "node_init"
}
void init_nodes(node *nodes) {
node_init(&nodes[0], 1, 1);
node_init(&nodes[1], 2, 4);
node_init(&nodes[2], 3, 1);
node_init(&nodes[3], 4, 4);
node_init(&nodes[4], 5, 4);
node_init(&nodes[5], 6, 2);
node_init(&nodes[6], 7, 5);
node_init(&nodes[7], 8, 3);
node_init(&nodes[8], 9, 2);
node_init(&nodes[9], 10, 2);
node_init(&nodes[10], 11, 4);
node_init(&nodes[11], 12, 2);
edge_init(&nodes[0], &nodes[1]);
edge_init(&nodes[1], &nodes[4]);
edge_init(&nodes[1], &nodes[6]);
edge_init(&nodes[1], &nodes[7]);
edge_init(&nodes[2], &nodes[3]);
edge_init(&nodes[3], &nodes[6]);
edge_init(&nodes[3], &nodes[7]);
edge_init(&nodes[3], &nodes[11]);
edge_init(&nodes[4], &nodes[5]);
edge_init(&nodes[4], &nodes[8]);
edge_init(&nodes[4], &nodes[9]);
edge_init(&nodes[5], &nodes[6]);
edge_init(&nodes[6], &nodes[9]);
edge_init(&nodes[6], &nodes[10]);
edge_init(&nodes[7], &nodes[10]);
edge_init(&nodes[8], &nodes[10]);
edge_init(&nodes[10], &nodes[11]);
}
void delete_nodes(node *nodes) {
for (int i = 0; i < 12; ++i) {
node_delete(&nodes[i]);
}
}
int main() {
node *nodes= new node[12];
init_nodes(nodes);
int sum_dfs = dfs_sum(&nodes[0]);
cout << endl;
int sum_loop = 0;
for (int i = 0; i < 12; ++i) {
sum_loop += nodes[i].value;
}
cout << "sum_dfs = " << sum_dfs << " sum_loop = " << sum_loop << endl;
delete_nodes(nodes);
delete [] nodes;
return 0;
}
I do not know how to begin this exercise
I am not familiar with c++ (I think that's what you used) but the implementation is the same anyway so I can give you a pseudo-code of what the algorithm should look like.
create a stack where object will be stored
all nodes are not visited when we begin
push source in the stack and mark it as visited
while the stack is not empty;
go to the first adjacent node to source and if it has not been visited
mark as visited and move to its next unvisited node and so on
if at any point you reach a node that cannot visited any other unvisited node
pop the stack until you can visited an unvisited node.
Do this until the stack is empty
Below is a simple implementation using an adjacency matrix
void dfs(int adjacency_matrix[][], int source){
Stack<Integer> stack = new Stack<>();
int numNodes = adjacency_matrix[source].length -1;
boolean [] visited = new boolean[numNodes +1];
visited[source] = true;
stack.add(source);
while(!stack.isEmpty()){
int current = stack.peek(); // don't remove the element but get it
System.out.println("Current node being visited is "+current);
for(int x = 0; x <= numNodes; x++){
if(adjacency_matrix[current][x] == 1 && visited[x] == false){
visited[x] = true;
stack.push(x);
break;
}else if(x == numNodes){
stack.pop();
}
}
}
}
You can test with a graph like this
0 --- 1-------5----6--8
| \ \ | / /
| \ \ | / /
| \ \ | / /
2 3----4---7---9
0 1 2 3 4 5 6 7 8 9
---------------------
0 | 0 1 1 1 0 0 0 0 0 0
1 | 1 0 0 0 1 1 0 0 0 0
2 | 1 0 0 0 0 0 0 0 0 0
3 | 1 0 0 0 1 0 0 0 0 0
4 | 0 1 0 1 0 0 0 1 0 0
5 | 0 1 0 0 0 0 1 1 0 0
6 | 0 0 0 0 0 1 0 1 1 0
7 | 0 0 0 0 1 1 1 0 0 1
8 | 0 0 0 0 0 0 1 0 0 1
9 | 0 0 0 0 0 0 0 1 1 0
---------------------

Understanding recursion better

In attempt to understand recursion better, I tried to print some output within my code so that I could study the steps.
#include <tuple>
#include <string>
#include <iostream>
#include <map>
#include "print.h"
std::tuple<int, int, int> find_max_crossing_subarray(int A[], int low, int mid, int high)
{
int max_left, max_right;
int left_sum = std::numeric_limits<int>::min();
int sum = 0;
for(int i = mid; i >= low; i--) {
sum += A[i];
if(sum > left_sum) {
left_sum = sum;
max_left = i;
}
}
int right_sum = std::numeric_limits<int>::min();
sum = 0;
for(int j = mid + 1; j <= high; j++) {
sum += A[j];
if(sum > right_sum) {
right_sum = sum;
max_right = j;
}
}
return std::make_tuple(max_left, max_right, left_sum + right_sum);
}
std::tuple<int, int, int> find_max_subarray(int A[], int low, int high)
{
if(high == low) {
return std::make_tuple(low, high, A[low]);
}
else {
int mid = (high + low) / 2;
std::tuple<int, int, int> left(find_max_subarray(A, low, mid));
std::cout << "left: ";
print(left);
int left_low, left_high, left_sum;
std::tie(left_low, left_high, left_sum) = left;
std::tuple<int, int, int> right(find_max_subarray(A, mid + 1, high));
std::cout << "right: ";
print(right);
int right_low, right_high, right_sum;
std::tie(right_low, right_high, right_sum) = right;
std::tuple<int, int, int> cross(find_max_crossing_subarray(A, low, mid, high));
std::cout << "cross: ";
print(cross);
int cross_low, cross_high, cross_sum;
std::tie(cross_low, cross_high, cross_sum) = cross;
if(left_sum >= right_sum && left_sum >= cross_sum) {
return left;
}
else if(right_sum >= left_sum && right_sum >= cross_sum) {
return right;
}
else {
return cross;
}
}
}
int main()
{
int arr_3[3] = {-3, 2, 3};
int arr_4[4] = {5, -23, 1, 44};
int arr_6[6] = {5, -23, 1, 44, -2, 5};
int arr[16] = {-23, 3, 9 ,7, -12, 87, -25, 2, 3, 5, 32, -8, 6, -82, 3, 9};
print(arr_4, 4);
std::tuple<int, int, int> maple(find_max_subarray(arr_4, 0, 3));
print(maple);
return 0;
}
OUTPUT::
5 -23 1 44
left: 0 0 5
right: 1 1 -23
cross: 0 1 -18
left: 0 0 5
left: 2 2 1
right: 3 3 44
cross: 2 3 45
right: 2 3 45
cross: 0 3 27
2 3 45
I understand the first three lines of the output (that is, where the left, right, cross begin). But I do not understand where the fourth line and beyond come from. I tried tracing back the functions and I keep thinking I should get left: 1 1 -23 in my fourth line of output after cross: 0 1 -18.
EDIT:
I should point out that after left: 2 2 1, although it's hard to visualize, I understand somewhat. The recursion has reached the end and the code is just cascading backwards.
SECOND EDIT:
I guess what is happening in the fourth line is that the very first find_max_subarray is completing and it is returning the first if statement in the function code. Now it is moving to the second find_max_subarray.
THIRD EDIT:
I guess my confusion is that the code doesn't cascade backwards but instead just returns to the very first call after it reaches the end of the recursion.
FOURTH EDIT:
When I go out to six elements though it seems like it doesn't simply return to the first call.
5 -23 1 44 -2 5
left: 0 0 5
right: 1 1 -23
cross: 0 1 -18
left: 0 0 5
right: 2 2 1
cross: 0 2 -17
left: 0 0 5
left: 3 3 44
right: 4 4 -2
cross: 3 4 42
left: 3 3 44
right: 5 5 5
cross: 3 5 47
right: 3 5 47
cross: 2 5 48
2 5 48
I mean I guess it's because the sub array has three elements as opposed to two. So there are two pairs as opposed to one. It makes sense when you take it for granted but can't see it visually.
LAST EDIT:
So when I go out to 8, it goes in pairs. First two elements and then return the original call. The next two pairs and return the call. I'm not exactly sure why though in the odd case it won't return the call until both the first and second and first and third pairs have completed.
5 -23 1 44 -2 5 6 -3
left: 0 0 5
right: 1 1 -23
cross: 0 1 -18
left: 0 0 5
left: 2 2 1
right: 3 3 44
cross: 2 3 45
right: 2 3 45
cross: 0 3 27
left: 2 3 45
left: 4 4 -2
right: 5 5 5
cross: 4 5 3
left: 5 5 5
left: 6 6 6
right: 7 7 -3
cross: 6 7 3
right: 6 6 6
cross: 5 6 11
right: 5 6 11
cross: 2 6 54
2 6 54
PROBLEM SOLVED:
The problem I was having in understanding the recursion is that for each recursive step I was using the original high value. I actually wrote it down on paper in blocks using the correct high and everything came together.
As stated above in my problem solved section following the last edit, I realized that in my analysis I was using the wrong value for high. I was not seeing this because although I was using blocks I was going in blocks of sequences and not blocks of blocks.
I went block by block with the updated high for each sub-block. I posted the illustration below. And this agrees with the output I was getting. The return statement accompanies each block.
Four element case:
(0,3)
(0,1)
(0,0) -> left
(1,1) -> right
-> cross
return left
(2,3)
(2,2) -> left
(3,3) -> right
-> cross
return right
return cross
Five element case:
(0,4)
(0,2)
(0,1)
(0,0) -> left
(1,1) -> right
-> cross
return left
(2,2) -> right
-> cross
return left
(3,4)
(3,3) -> left
(4,4) -> right
-> cross
return right
return cross