Trying to find depth of binary tree - c++

I'm trying to write something to determine the largest depth of a binary tree but far have only ended up with one thing that keep giving back the number of nodes in the tree, and another, below, that is always one more or less off. After hours of trying to adjust this I could really use some advice..
void findthedepth(nodeoftree<node>* root, int* depthtotal, int* depthcurrent){
int left = 0, right = 0;
if( root == nullptr ){
*depthtotal = 0;
*depthcurrent = 0;
return;
}
findthedepth(root->rightp(), depthtotal, depthcurrent);
right = *depthcurrent;
*depthcurrent = 0;
findthedepth(root->leftp(), depthtotal, depthcurrent);
left = *depthcurrent;
if (left > right){
*depthtotal += left + 1;
}
else {
*depthtotal += right + 1;
}
}

There are two cases to consider:
An empty tree has depth zero;
A non-empty tree has one level more than the depth of its two subtrees, so it has depth 1 + max(depth_left, depth_right).
If we write this out in C++:
int depth(nodeoftree<node>* root) {
if (root == nullptr)
return 0;
int depth_left = depth(node->leftp());
int depth_right = depth(node->rightp());
return 1 + max(depth_left, depth_right);
}

You are very close, you don't need the depthCurrent pointer
findthedepth(root->rightp(), depthtotal /*, depthcurrent*/);
right = *depthtotal; // update the total depth captured in right
// *depthcurrent = 0; (no use)
findthedepth(root->leftp(), depthtotal /*, depthcurrent*/);
left = *depthtotal; // update the total depth captured in left

Related

Can't find the correct startvalue for FloodFill implementation in C++

I am trying to fill everything that is outside a contour using a queue implementation of flood fill. However i have some problems deducing the starting point to add to the queue.
I define a new double of 400*400 named tmpSlice and fill it with zeroes. Then i map the contour with label value 1.0. This part works just fine.
The problem occurs when i have to push a starting point onto the queue the best scenario would be to push the top left corner or point 0.
However i can not push 0 as a starting point without getting a segmentation fault. I am currently pushing 160000 which is the size of tmpSlice this is the only number i have been able to insert without errors.
However when i am pushing 160000 onto the queue and after the flood fill has executed i run the loop(at bottom of code) that runs from 0-160000.
This loop should color everything which has value 0 and 1 as one and everything that has value 2 should be zero. But currently everything inside the tmpSlice has value 0 except the original contour that has value 1.
For clarification 2 represents the outside of the contour, 1 represents the border of the contour and 0 represents whats inside the contour
So basically the flood fill does nothing on my dataset tmpSlice. I think it is because of the starting point inserted onto the queue but i haven't been able to insert any values that will work.
Thoughts?
PS.
I am limited to use the new double because a vector::std doesn't work with some functions from the minc library that i am using.
/* Flood fill */
//Colour we are looking for as background
int TargetColour = 0.0;
//The new colour we will write
int NewColour = 2.0;
//create set to secure unique entries into the queue, otherwise we etc. insert the 9th element in a 3x3 array 6 times.
set < int > Set;
//Create queue
queue < int > MyQue;
//Insert first point into the queue
MyQue.push(sizes[1]*sizes[2]);
int Node;
//While loop for iterating over the nodes.
while (!MyQue.empty()){
//Set front element to Node, and pop the front element from queue
Node = MyQue.front();
MyQue.pop();
//Change the colour to newcolour
tmpSlice[Node] = NewColour;
//Define the Node directions
int WestNode = Node-1;
int EastNode = Node+1;
//sizes are the lengths x,y
int NorthNode = Node-sizes[1];
int SouthNode = Node+sizes[2];
//Boundary checks
EastNodeBoundaryCheck = floor((Node-sizes[1]*sizes[2]*floor(Node/(sizes[1]*sizes[2])))/sizes[1]) == floor((EastNode-sizes[1]*sizes[2]*floor(EastNode/(sizes[1]*sizes[2])))/sizes[1]);
SouthNodeBoundaryCheck = floor(Node / (sizes[1]*sizes[2])) == floor(SouthNode / (sizes[1]*sizes[2]));
WestNodeBoundaryCheck = floor((Node-sizes[1]*sizes[2]*floor(Node/(sizes[1]*sizes[2])))/sizes[1]) == floor((WestNode-sizes[1]*sizes[2]*floor(WestNode/(sizes[1]*sizes[2])))/sizes[1]);
NorthNodeBoundaryCheck = floor(Node / (sizes[1]*sizes[2])) == floor(NorthNode / (sizes[1]*sizes[2]));
//East Node
if (Set.insert(EastNode).second) {
if (tmpSlice[EastNode] == TargetColour && EastNodeBoundaryCheck == 1){
MyQue.push(EastNode);
}
}
//South Node
if (Set.insert(SouthNode).second) {
if (tmpSlice[SouthNode] == TargetColour && SouthNodeBoundaryCheck == 1){
MyQue.push(SouthNode);
}
}
//West Node
if (Set.insert(WestNode).second) {
if (tmpSlice[WestNode] == TargetColour && WestNodeBoundaryCheck == 1){
MyQue.push(WestNode);
}
}
//North Node
if (Set.insert(NorthNode).second) {
if (tmpSlice[NorthNode] == TargetColour && NorthNodeBoundaryCheck == 1){
MyQue.push(NorthNode);
}
}
}
// Insert the colored points as 0 and everything else as 1
for(i = 0; i < sizes[1]*sizes[2]; i++){
if(tmpSlice[i] == 0.0 || 1.0){
slab[first_voxel_at_slice + i] = 1.0;
}
if(tmpSlice[i] == 2.0){
slab[first_voxel_at_slice + i] = 0.0;
}
}
I found the answer myself when answering a comment :-)
I needed to check the NorthNode if it was bigger than 0 for the first row to avoid segmentation fault.
//North Node
if (Set.insert(NorthNode).second) {
if (NorthNode > 0){
if (tmpSlice[NorthNode] == TargetColour && NorthNodeBoundaryCheck == 1){
MyQue.push(NorthNode);
}
}
}

How to sum up the child values that starts from child to root in a tree structure?

I want to get the absolute values of each node. Absolute value meaning that the distance from the root.
if I have a skeleton model.
the root childs are
root
left hip - child
left knee - child
left foot - child
assume that all the bones lengths are equal to 1.
root to hip = 1
hip to knee = 1
knee to foot = 1
So if I want to get the position of foot joint from the root, it should be 3. am I right?
root to foot = root to hip + hip to knee + knee to foot = 3
so these are the subroutines I am using..
void ComputeAbs()
{
for(unsigned int i=1; i<nNodes(); i++)
{
node* b = getNode(i);
if(b)
{
b->nb = ComputeAbsSum(b);
}
}
}
int ComputeAbsSum(node *b)
{
int m = b->nb;
if (b->child != NULL)
{
m *= ComputeAbsSum(b->child);
}
return m;
}
the output would be like
root to hip = 3
root to knee = 2
root to foot = 1
But I want in a reverse way, i should get like this
root to hip = 1
root to knee = 2
root to foot = 3
How can I achieve this result? how to add tree childs values starts from child to root?
the final objective is to get the final pose by calculating the absolute transformation of a joint.
bonePoseAbsolute[i] = bonePoseAbsolute[parentIndex] * bonePoseRelative[i];
Thanks.
It looks like you have a problem in your recursion. Try
int ComputeAbsSum(node *b)
{
int result = 1;
if (b->child != NULL)
result += ComputeAbsSum(b->child);
return result;
}
*edit: if you want to traverse the tree in reverse,
int ComputeAbsSumReverse(node *b)
{
int result = 1;
if (b->parent != NULL)
result += ComputeAbsSum(b->parent);
return result;
}

Depth First Search: Formatting output?

If I have the following graph:
Marisa Mariah
\ /
Mary---Maria---Marian---Maryanne
|
Marley--Marla
How should be Depth First Search function be implemented such that I get the output if "Mary" is my start point ?
Mary
Maria
Marisa
Mariah
Marian
Maryanne
Marla
Merley
I do realize that the number of spaces equal to depth of the vertex( name ) but I don't how to code that. Following is my function:
void DFS(Graph g, Vertex origin)
{
stack<Vertex> vertexStack;
vertexStack.push(origin);
Vertex currentVertex;
int currentDepth = 0;
while( ! vertexStack.empty() )
{
currentVertex = vertexStack.top();
vertexStack.pop();
if(currentVertex.visited == false)
{
cout << currentVertex.name << endl;
currentVertex.visited = true;
for(int i = 0; i < currentVertex.adjacencyList.size(); i++)
vertexStack.push(currentVertex.adjacencyList[i]);
}
}
}
Thanks for any help !
Just store the node and its depth your stack:
std::stack<std::pair<Vertex, int>> vertexStack;
vertexStack.push(std::make_pair(origin, 0));
// ...
std::pair<Vertex, int> current = vertexStack.top();
Vertex currentVertex = current.first;
int depth = current.second;
If you want to get fancy, you can extra the two values using std::tie():
Vertex currentVertex;
int depth;
std::tie(currentVertex, depth) = vertexStack.top();
With knowing the depth you'd just indent the output appropriately.
The current size of your stack is, BTW, unnecessarily deep! I think for a complete graph it may contain O(N * N) elements (more precisely, (N-1) * (N-2)). The problem is that you push many nodes which may get visited.
Assuming using an implicit stack (i.e., recursion) is out of question (it won't work for large graphs as you may get a stack overflow), the proper way to implement a depth first search would be:
push the current node and edge on the stack
mark the top node visited and print it, using the stack depth as indentation
if there is no node
if the top nodes contains an unvisited node (increment the edge iterator until such a node is found) go to 1.
otherwise (the edge iterator reached the end) remove the top node and go to 3.
In code this would look something like this:
std::stack<std::pair<Node, int> > stack;
stack.push(std::make_pair(origin, 0));
while (!stack.empty()) {
std::pair<Node, int>& top = stack.top();
for (; top.second < top.first.adjacencyList.size(); ++top.second) {
Node& adjacent = top.first.adjacencyList[top.second];
if (!adjacent.visited) {
adjacent.visted = true;
stack.push(std::make_pair(adjacent, 0));
print(adjacent, stack.size());
break;
}
}
if (stack.top().first.adjacencyList.size() == stack.top().second) {
stack.pop();
}
}
Let Rep(Tree) be the representation of the tree Tree. Then, Rep(Tree) looks like this:
Root
<Rep(Subtree rooted at node 1)>
<Rep(Subtree rooted at node 2)>
.
.
.
So, have your dfs function simply return the representation of the subtree rooted at that node and modify this value accordingly. Alternately, just tell every dfs call to print the representation of the tree rooted at that node but pass it the current depth. Here's an example implementation of the latter approach.
void PrintRep(const Graph& g, Vertex current, int depth)
{
cout << std::string(' ', 2*depth) << current.name << endl;
current.visited = true;
for(int i = 0; i < current.adjacencyList.size(); i++)
if(current.adjacencyList[i].visited == false)
PrintRep(g, current.adjacencyList[i], depth+1);
}
You would call this function with with your origin and depth 0 like this:
PrintRep(g, origin, 0);

Implementing Alpha Beta into Minimax

I'm trying to add Alpha Beta pruning into my minimax, but I can't understand where I'm going wrong.
At the moment I'm going through 5,000 iterations, where I should be going through approximately 16,000 according to a friend. When choosing the first position, it is returning -1 (a loss) whereas it should be able to definitely return a 0 at this point (a draw) as it should be able to draw from an empty board, however I can't see where I'm going wrong as I follow my code it seems to be fine
Strangely if I switch returning Alpha and Beta inside my checks (to achieve returning 0) the computer will attempt to draw but never initiate any winning moves, only blocks
My logical flow
If we are looking for alpha:
If the score > alpha, change alpha. if alpha and beta are overlapping, return alpha
If we are looking for beta:
If the score < beta, change beta. if alpha and beta are overlapping, return beta
Here is my
Recursive call
int MinimaxAB(TGameBoard* GameBoard, int iPlayer, bool _bFindAlpha, int _iAlpha, int _iBeta)
{
//How is the position like for player (their turn) on iGameBoard?
int iWinner = CheckForWin(GameBoard);
bool bFull = CheckForFullBoard(GameBoard);
//If the board is full or there is a winner on this board, return the winner
if(iWinner != NONE || bFull == true)
{
//Will return 1 or -1 depending on winner
return iWinner*iPlayer;
}
//Initial invalid move (just follows i in for loop)
int iMove = -1;
//Set the score to be instantly beaten
int iScore = INVALID_SCORE;
for(int i = 0; i < 9; ++i)
{
//Check if the move is possible
if(GameBoard->iBoard[i] == 0)
{
//Put the move in
GameBoard->iBoard[i] = iPlayer;
//Recall function
int iBestPositionSoFar = -MinimaxAB(GameBoard, Switch(iPlayer), !_bFindAlpha, _iAlpha, _iBeta);
//Replace Alpha and Beta variables if they fit the conditions - stops checking for situations that will never happen
if (_bFindAlpha == false)
{
if (iBestPositionSoFar < _iBeta)
{
//If the beta is larger, make the beta smaller
_iBeta = iBestPositionSoFar;
iMove = i;
if (_iAlpha >= _iBeta)
{
GameBoard->iBoard[i] = EMPTY;
//If alpha and beta are overlapping, exit the loop
++g_iIterations;
return _iBeta;
}
}
}
else
{
if (iBestPositionSoFar > _iAlpha)
{
//If the alpha is smaller, make the alpha bigger
_iAlpha = iBestPositionSoFar;
iMove = i;
if (_iAlpha >= _iBeta)
{
GameBoard->iBoard[i] = EMPTY;
//If alpha and beta are overlapping, exit the loop
++g_iIterations;
return _iAlpha;
}
}
}
//Remove the move you just placed
GameBoard->iBoard[i] = EMPTY;
}
}
++g_iIterations;
if (_bFindAlpha == true)
{
return _iAlpha;
}
else
{
return _iBeta;
}
}
Initial call (when computer should choose a position)
int iMove = -1; //Invalid
int iScore = INVALID_SCORE;
for(int i = 0; i < 9; ++i)
{
if(GameBoard->iBoard[i] == EMPTY)
{
GameBoard->iBoard[i] = CROSS;
int tempScore = -MinimaxAB(GameBoard, NAUGHT, true, -1000000, 1000000);
GameBoard->iBoard[i] = EMPTY;
//Choosing best value here
if (tempScore > iScore)
{
iScore = tempScore;
iMove = i;
}
}
}
//returns a score based on Minimax tree at a given node.
GameBoard->iBoard[iMove] = CROSS;
Any help regarding my logical flow that would make the computer return the correct results and make intelligent moves would be appreciated
Does your algorithm work perfectly without alpha-beta pruning? Your initial call should be given with false for _bFindAlpha as the root node behaves like an alpha node, but it doesn't look like this will make a difference:
int tempScore = -MinimaxAB(GameBoard, NAUGHT, false, -1000000, 1000000);
Thus I will recommend for you to abandon this _bFindAlpha nonsense and convert your algorithm to negamax. It behaves identically to minimax but makes your code shorter and clearer. Instead of checking whether to maximize alpha or minimize beta, you can just swap and negate when recursively invoking (this is the same reason you can return the negated value of the function right now). Here's a slightly edited version of the Wikipedia pseudocode:
function negamax(node, α, β, player)
if node is a terminal node
return color * the heuristic value of node
else
foreach child of node
val := -negamax(child, -β, -α, -player)
if val ≥ β
return val
if val > α
α := val
return α
Unless you love stepping through search trees, I think that you will find it easier to just write a clean, correct version of negamax than debug your current implementation.

BST in array traversal

I have the following implementation of a binary tree in an array;
32
/ \
2 -5
/ \
-331 399
The data is grouped 3 indexes at a time. index%3==0 is the value of the node, index%3==1 is the index of the value of the left node and index%3==2 is the index of the value of the right node. If the left or right index reference is 0, there is no node that direction.
I'm trying to find the depth (height) of this tree. I've written it recursively
height(node):
if node == null:
return 0
else:
return max(height(node.L), height(node.R)) + 1
I want to find a non-recursive solution, however.
Here is some pseudocode i have, assuming the tree is not empty
int i = 0; int left = 0; int right = 0;
while (i != n ){
if ( a[i+1] != 0 ){
left++;
}
else if ( a[i+2] != 0 ){
right++;
}
i = i + 3;
}
return max ( left, right ) + 1;
I don't think this is right and I'd like some help figuring out how to do this correctly.
You haven't said what your problem is with recursion for us to understand what behavior you want to improve.
There are many solutions to this, but almost all of them have the same or worse performance than your recursive solution. Really, the best solutions are going to be things you'd have to do when you're creating the tree. For example, you could store the height of each node in a fourth array index per node. Then it's a trivial scan of every fourth index to find the max height. It would also make it easier if nodes had parent references stored with them so that didn't have to be computed during the height check.
One solution is to simulate recursion with a stack, but that's really no different than recursion.
Another solution is to go through each node and determine its height based on it's parent, but not in a specific traversal's order. However, because of how you have this configured, without a secondary datastructure to store the hierarchy, it's going to be less efficient O(n^2). The problem is you can't get from the child to its parent without a full array scan. Then you can do it in linear time (but recursion is also linear time, so I'm not sure we're doing better. It's also not going to be much better from a memory perspective).
Can you define what type of efficiency you want to improve?
Here's the pseudocode for each, but I'm depending on a few datastructures that aren't easily present:
"recursion without recursion" solution:
int get_height(int * tree, int length) {
Stack stack;
int max_height = 0;
if (length == 0) {
return 0;
}
// push an "array" of the node index to process and the height of its parent.
// make this a struct and use that for real c code
stack.push(0,0);
while(!stack.empty()) {
int node_index, parent_height = stack.pop();
int height = parent_height + 1;
if (height > max_height) {
max_height=height;
}
if (tree[node_index+1] != 0 )
stack.push(tree[node_index+1], height);
if (tree[node_index+2] != 0 )
stack.push(tree[node_index+2], height);
}
return max_height;
}
Now working on really slow solution that uses no additional memory, but it's REALLY bad. It's like writing fibonacci recursively bad. The original algorithm went through each node and performed O(n) checks worst case for a runtime of O(n^2) (actually not quite as bad as I had originally thought)
edit: much later I'm adding an optimization that skips all nodes with children. This is REALLY important, as it cuts out a lot of calls. Best case is if the tree is actually a linked list, in which case it runs in O(n) time. Worst case is a fully balanced tree - with logn leaf nodes each doing logn checks back to the root for O((log(n)^2). Which isn't nearly so bad. Lines below to be marked as such
"really slow but no extra memory" solution (but now updated to not be nearly so slow):
int get_height(int * tree, int length) {
int max_height = 0;
for (int i = 0; i < length; i+=3) {
// Optimization I added later
// if the node has children, it can't be the tallest node, so don't
// bother checking from here, as the child will be checked
if (tree[i+1] != 0 || tree[i+2] != 0)
continue;
int height = 0;
int index_pointing_at_me;
// while we haven't gotten back to the head of the tree, keep working up
while (index_pointing_at_me != 0) {
height += 1;
for (int j = 0; j < length; j+=3) {
if (tree[j+1] == tree[i] ||
tree[j+2] == tree[i]) {
index_pointing_at_me = j;
break;
}
}
}
if (height > max_height) {
max_height = height;
}
}
return max_height;
}
Improved on previous solution, but uses O(n) memory - this assumes parents are always before children in array (which I suppose isn't technically required)
int get_height(int * tree, int length) {
if (length == 0)
return 0;
// two more nodes per node - one for which node is its parent, the other for its height
int * reverse_mapping = malloc((sizeof(int) * length / 3) * 2)
reverse_mapping[1] = 1; // set height to 1 for first node
// make a mapping from each node to the node that points TO it.
// for example, for the first node
// a[0] = 32
// a[1] = 3
// a[2] = 6
// store that the node at 3 and 6 are both pointed to by node 0 (divide by 3 just saves space since only one value is needed) and that each child node is one taller than its parent
int max_height = 0;
for (int i = 0; i < length; i+=3) {
int current_height = reverse_mapping[(i/3)*2+1];
if (current_height > max_height)
max_height = current_height;
reverse_mapping[(tree[i+1]/3)*2] = i;
reverse_mapping[(tree[i+1]/3)*2 + 1] = current_height + 1;
reverse_mapping[(tree[i+2]/3)*2] = i;
reverse_mapping[(tree[i+2]/3)*2 + 1] = current_height + 1;
}
return max_height
}