recursion

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

recursion

Post by arukomp »

Hello,

I'm using recursion method to show tree. Now i need to look at that tree and find the nearest node which has less than 3 children nodes and return that node.

Here's the code i created so far:

Code: Select all

function findref2($refid){
	$result = mysql_query("SELECT id FROM users WHERE refid='$refid'");
	if (mysql_num_rows($result) < 3) {
		return $refid;
		exit;
	}
	elseif (mysql_num_rows($result) >= 3) {
		while($row = mysql_fetch_array($result)){
		 	findref2($row['id']);
		} // while
	}
}

$ref2 = findref2(2);
Everything works good until the first node has less than 3 children. When elseif is chosen, the function doesn't return anything, so in MySQL database refid is saved as 0.

Can anyone help me with this problem? Why it doesn't return anything if there are more instances of this function?

Thanks for answers
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

elseif (mysql_num_rows($result) >= 3) {
while($row = mysql_fetch_array($result)){
findref2($row['id']);
} // while
}
There's no return statement in this block.
arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

Post by arukomp »

Yeah, but there's in the first block. In the second block it calls the function itself with different refid, so there are more instances of function, but only one of them will execute the first if statement, which should return a recent used refid
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Who cares about what happens in the first block if you're in the second block? If you want all code paths to return something you'll need a return statement there too...
arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

Post by arukomp »

yeah, but this function keeps running until it executes the first if statement, which returns a value and exits.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

But the 'returning' is only done to calling level.. It's not moved up in the call chain

eg:

Code: Select all

function foo() {
 return 5;
}

function bar() {
  foo();
}
bar returns void.. where you seem to think that it would return 5.
arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

Post by arukomp »

timvw wrote:But the 'returning' is only done to calling level.. It's not moved up in the call chain

eg:

Code: Select all

function foo() {
 return 5;
}

function bar() {
  foo();
}
bar returns void.. where you seem to think that it would return 5.
well, yeah :)

any suggestions how can i fix it?
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

Code: Select all

if (mysql_num_rows($result) < 3) {
	return $refid;
}
elseif (mysql_num_rows($result) >= 3) {
 // what is the function supposed to return in this case?
}
Just explain it in your own words, without code, but think a while about it.
arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

Post by arukomp »

ok, starting over.

The function i want to create is supposed to control spillover. The script is a forced matrix, 3x9, so there can't be more than 3 members under the first level of each person.

Lets say that new user has joined. His sponsor already has 3 members under his 1st level, so we need to find the nearest member in sponsor's downline, which doesn't have 3 members under his 1st level. Then we need to return that member's id and insert the new user's data and place him under that member.

This is what i want to do. I told this, because maybe there's another and better way to do this.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

It would seem that a hierarchical structure may be more useful as it's simple math to engineer the result set you want.

http://www.sitepoint.com/print/1105
arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

Post by arukomp »

feyd wrote:It would seem that a hierarchical structure may be more useful as it's simple math to engineer the result set you want.

http://www.sitepoint.com/print/1105
I've read it all a day ago. I've chosen the first method to keep work hierarchical data. But i don't know how to find the nearest node, which has less than 3 children.

Again...

The function i want to create is supposed to control spillover. The script is a forced matrix, 3x9, so there can't be more than 3 members under the first level of each person.

Lets say that new user has joined. His sponsor already has 3 members under his 1st level, so we need to find the nearest member in sponsor's downline, which doesn't have 3 members under his 1st level. Then we need to return that member's id and insert the new user's data and place him under that member.

This is what i want to do. I told this, because maybe there's another and better way to do this.
arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

Post by arukomp »

No one knows? :(
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

arukomp wrote:ok, starting over.
Why? Couldn't you just try to answer only the specific question instead of describing the whole function+purpose?
arukomp
Forum Contributor
Posts: 113
Joined: Sun Sep 24, 2006 4:22 am

Post by arukomp »

volka wrote:

Code: Select all

if (mysql_num_rows($result) < 3) {
	return $refid;
}
elseif (mysql_num_rows($result) >= 3) {
 // what is the function supposed to return in this case?
}
Just explain it in your own words, without code, but think a while about it.
In this case, the function shouldn't return anything. It should start the function again with another $refid value. It should keep doing that until one instance of the function executes the first if statement. Then it returns $refid value, which was used in that function.
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

Ok, you still haven't understood how functions and return work.
If the function does not return anything in this case ...it does not return anything, nada, njiente. It does not matter wether a function calls itself or another function. If the function calls itself it's still a function call.
There's something called call stack. You can put a new item on the stack and you can remove the topmost item. But if you want to remove an item below other items you first have to remove all the items above. That's how function calls work. e.g.

Code: Select all

function foo() {
	return 3;
}

function bar() {
	$v = foo();
	echo 'v: ', $v, "<br />\n";
}

$v = bar();
echo 'v: ', $v, "<br />\n";
when the script's execution reaches the line return 3; the call stack looks like
foo <- bar <- [main]
foo is still executed. When it's done the script continues with the code in bar() after the call of foo(). When bar() is done [main] continues after the call of bar().
A return value is only available to next topmost item on the call stack. So foo() can only return a value to bar(). If bar() doesn't pass that value to [main] it's lost.
The same is true if bar() calls itself.

Code: Select all

function bar($param) {
	if ( 0==$param) {
		return 'xyz';
	}
	else {
		bar($param-1);
	}
}

$v = bar(1);
echo $v;
When bar() is called the first time ( bar(1) ) the call stack is bar<-[main]. Let's add the parameters to the call stack: bar(1)<-[main]
$param is not 0, therefore the else-block is executed and bar calls itself, this time with the parameter 1-1=0, call stack: bar(0)<-bar(1)<-[main]
Questions: whereto does return 'xyz'; return the string? What happens next?
Post Reply