473,404 Members | 2,213 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

Recursion problems - how does it work?

csx
Hi all,
Ive got a problem with recursion in Javascript.
For this tree:
http://www.pcm.uklinux.net/structure.jpg

If you input node 3 (i.e. C) which is represented as 'values[2]' in the
array, it should return all the 'leaf' nodes. In this case 4!
Node 4 (i.e. D) is not included in the count.

In C, this function works perfectly:
int countLeafNodes(node& parentNode)
{
int sum = 0;
for (int j=0; j<nodes.size(); j++) {
if (parentNode.key == nodes[j].parent)
{
sum += countLeafNodes(nodes[j]);
}
}
return ((sum==0)?1:sum); // if node has no children sum is 0
}
I've tried to replicate this code in Javascript. But the recursion just
doesnt work. Has anyone got any suggestions? Any help would be much
appreciated.

Here's the JavaScript code at the moment.
<html>
<head>

<script language="javascript">
function values(key, row, desc, parent)
{
this.key = key;
this.row = row;
this.desc = desc;
this.parent = parent
}
</script>

<script language="javascript">
function countLeafNodes(valuesCell)
{
var sum = 0;
temp = valuesCell.key;

for (n=0; n < valuesCell.length; n++)
{
if (temp == valuesCell[n].parent)
{
sum += countLeafNodes(valuesCell[n]);
}
}

if (sum == 0) {
return 1; }
else {
return sum;
}

</head>
<body>
values = new Array();

values[0] = new information(1, 1,'A',0);
values[1] = new information(2, 2,'B',1);
values[2] = new information(3, 2,'C',1);
values[3] = new information(4, 3,'D',3);
values[4] = new information(5, 3,'E',3);
values[5] = new information(6, 4,'F',4);
values[6] = new information(7, 4,'G',4);
values[7] = new information(8, 4,'H',4);

var cols = countLeafNodes(values[2]);
document.write("The number of cols is: " + cols + "<br>");

</script>

</body>
</html>
Jul 20 '05 #1
3 4665
csx
I've changed it around a bit. But still no luck. I've been reading some
Javascript sites and I was wondering, do I need to use
arguments.callee
to get the recursion working? The examples are confusing. Some use it some
dont.

<html>
<head>
</head>
<body>

<script language="javascript">
function information(key, row, desc, parent)
{
this.key = key;
this.row = row;
this.desc = desc;
this.parent = parent
}

function countLeafNodes(valuesCell)
{
var sum = 0;
temp = valuesCell.key;

for (n=0; n < values.length; n++)
{
if (temp == values[n].parent)
{
sum += countLeafNodes(n);
}
}

if (sum == 0) {
return 1; }
else {
return sum;
}
}

values = new Array();
values[0] = new information(1, 1,'A',0);
values[1] = new information(2, 2,'B',1);
values[2] = new information(3, 2,'C',1);
values[3] = new information(4, 3,'D',3);
values[4] = new information(5, 3,'E',3);
values[5] = new information(6, 4,'F',4);
values[6] = new information(7, 4,'G',4);
values[7] = new information(8, 4,'H',4);

var cols = countLeafNodes(values[2]);
document.write("The number of cols is: " + cols + "<br>");

</script>
</body>
</html>
Jul 20 '05 #2
On Sun, 5 Oct 2003 20:19:54 +0000 (UTC), "csx" <cs*@ms.com> wrote:
Ive got a problem with recursion in Javascript.
For this tree:
http://www.pcm.uklinux.net/structure.jpg

If you input node 3 (i.e. C) which is represented as 'values[2]' in the
array, it should return all the 'leaf' nodes. In this case 4!
Node 4 (i.e. D) is not included in the count.

In C, this function works perfectly:
int countLeafNodes(node& parentNode)
{
int sum = 0;
for (int j=0; j<nodes.size(); j++) {
if (parentNode.key == nodes[j].parent)
{
sum += countLeafNodes(nodes[j]);
}
}
return ((sum==0)?1:sum); // if node has no children sum is 0
}

The comment on the last line is wrong...

So are you a C programmer or did you find this example somewhere and
tried to translate it to this javascript:
function countLeafNodes(valuesCell)
{
var sum = 0;
temp = valuesCell.key; This must be "var temp ...". var makes the variable a local variable
while not using var makes it global. You have to be especially aware
of the scope of your variables when you're dealing with recursion.

for (n=0; n < values.length; n++) Must be "var n=0". See above.
{
if (temp == values[n].parent)
{
sum += countLeafNodes(n); This is a problem I'll come back to shortly...
}
}

if (sum == 0) {
return 1; }
else {
return sum;
}
I would have left this written as
return ((sum==0)?1:sum);
or as
if (0 == sum)
sum = 1;
return sum;
for readability.

My guess is that you didn't write that C code, because if you had
you'd have been able to write the same thing in Javascript. You'll
have trouble writing a recursive function if you don't understand
what's going on. Try following your code and you'll find out pretty
quickly why you get a result of 1 instead of 4.

Code: var cols = countLeafNodes(values[2]);
Result: countLeafNodes gets the key property of values[2] which is 3
and then loops through the values array looking for items with a
parent property equal to 3. It finds the values[2] node, and calls
countLeafNodes(n).

<execution recurses into countLeafNodes>

Code: sum += countLeafNodes(n)
Result: countLeafNodes gets the key property of n which is undefined
because n is a number, not an object. (This is your main problem.)
Then it loops through the values array, looking for items with a key
property of undefined and obviously finds 0 nodes.

Code: if (sum == 0) return 1
Result: sum is 0, so returns 1

<execution leaves the recursive call to countLeafNodes, back to the
original countLeafNodes call>

The original countLeafNodes call is still in the loop. No more nodes
have a key value of 3 so no more calls to countLeafNodes are made and
at the end of the loop sum is still equal to 1.
I've changed it around a bit. But still no luck. I've been reading some
Javascript sites and I was wondering, do I need to use
arguments.callee
to get the recursion working? The examples are confusing. Some use it some
dont.


Recursion is primarily used for tree-like data structures. Your data
structure is flat (a simple array) though it logically describes a
tree which is not particularly an efficient way of doing things. That
said, this is the correct translation of the C code to work with your
flat data structure.

function countLeafNodes(valuesCell)
{
var sum = 0;
var temp = valuesCell.key;

for (var n=0; n < values.length; n++)
{
if (temp == values[n].parent)
{
sum += countLeafNodes(values[n]);
}
}

return (sum == 0 ? 1 : sum);
}

If you want to learn something, step through and figure out why you
need to use "var" with your temp and n variables, and why you have to
pass values[n] instead of n to countLeafNodes.

Now that the flat data structure is out of the way, here's the same
thing but with a tree structure.

<script language="javascript">
function information(key, desc)
{
this.key = key;
this.desc = desc;
this.parent = null;
this.row = 1;
this.subnodes = new Array();

this.addSubNode = function (node)
{
// Add the node to the subnodes array
this.subnodes.push(node);

// Set the node's parent and row
node.parent = this;
node.row = this.row + 1;

return node;
}

this.findNodeByKey = function (key)
{
var node = null;

if (this.key == key)
{
// This is the node we're looking for
node = this;
}
else
{
// Search each of the subnodes
for (var i=0; i<this.subnodes.length; i++)
{
// Another recursive function call...
node = this.subnodes[i].findNodeByKey(key);

// Stop looping when we've found the node
if (node)
break;
}
}

return node;
}
}

function countLeafNodes(node)
{
var sum = 0;

if (node.subnodes.length == 0)
{
// There are no subnodes so this is a leaf node
sum = 1;
}
else
{
// Recurse down through the subnodes
for (var i=0; i<node.subnodes.length; i++)
sum += countLeafNodes(node.subnodes[i]);
}

return sum;
}
// Build the tree structure.
// Notice that there is no parent or row information here.
// They are set correctly by addSubNode.

root = new information(1, 'A');

root.addSubNode(new information(2, 'B'));
C_node = root.addSubNode(new information(3, 'C'));

D_node = C_node.addSubNode(new information(4, 'D'));
C_node.addSubNode(new information(5, 'E'));

D_node.addSubNode(new information(6, 'F'));
D_node.addSubNode(new information(7, 'G'));
D_node.addSubNode(new information(8, 'H'));

// Count the leaf nodes under the C node
// Note: I could have used C_node instead of root.findNodeByKey(3)
// but that would have been no fun...
var cols = countLeafNodes(root.findNodeByKey(3));

document.write("The number of cols is: " + cols + "<br>");

</script>

Regards,
Steve
Jul 20 '05 #3
csx
Steve,
Thankyou so much for the time and effort in helping!

kind regards!
Jul 20 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: paulw | last post by:
Hi Please give problems that "HAS TO" to use recursion (recursive calls to itself.) Preferrably real world examples, not knights tour. I'm thinking about eliminating the use of stack... ...
5
by: Ioannis Vranos | last post by:
The following code is supposed to print all folder names of a folder but it does not work. Why? Change the folder in main() to a folder suitable for your system so as to test it. I created...
9
by: John Pass | last post by:
I am trying to understand how recursion exactly works. See example (section) below: Say i = 4, then Number = 4 during 1st loop. Is Factorial(number - 1) automatically recognised as a recursive...
2
by: Csaba Gabor | last post by:
I suppose spring fever has hit at alt.math.undergrad since I didn't get any rise from them when I posted this a week ago, so I am reposting this to some of my favorite programming groups: I'm...
19
by: Kay Schluehr | last post by:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691
12
by: NOO Recursion | last post by:
Hi everyone! I am trying to write a program that will search a 12x12 for a thing called a "blob". A blob in the grid is made up of asterisks. A blob contains at least one asterisk. If an...
10
by: elventear | last post by:
Hello everyone, I am runing into recursion limit problems. I have found that the culprit was related to the __hash__ function that I had assigned to the objects that were added to a set. ...
20
by: athar.mirchi | last post by:
..plz define it.
30
by: Jeff Bigham | last post by:
So, it appears that Javascript has a recursion limit of about 1000 levels on FF, maybe less/more on other browsers. Should such deep recursion then generally be avoided in Javascript?...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.