Recursive recursive and cyclic examples of JavaScript introduction _javascript Tips

Source: Internet
Author: User
Tags gcd repetition
recursion and Loop

For the different types of problems that need to be repeated, the two methods of circulation and recursion have their own advantages and can give a more intuitive and simple scheme. On the other hand, loops and recursive methods can be converted to each other. Any loop of code can be rewritten recursively to achieve the same function, and vice versa. Without losing its universality, loops and recursion can be summed up in the following pseudo code, respectively.

Pseudo-code Format description: The loop takes the while form, the variable is not defined, the assignment is: =; the conditional expression and the executed statement are written in the form of a function, and the relevant values are written in parentheses. Other grammatical aspects, as close as possible to JavaScript specifications.
Copy Code code as follows:

Pseudo code of a loop
While form
function loop (arguments) {
The initial value of the result
Result:=initial_value;

while (condition (variable, arguments)) {//Loop condition, may only be arguments, or it may be convenient to introduce the loop variable
Calculated results. Parameters include previous results, current loop variables, and external variables
Result:=calculate (result, variable, extern_variables);
Affects the external environment of the function, that is, modifying external variables
Changestatus (result, variable, extern_variables);
After executing the statement in the loop body, modify the parameter or loop variable.
modify_arguments_variable (arguments, variable);
}
return results
return result;
}

We also give the pseudo code of recursive functions.
Copy Code code as follows:

Pseudo code of a recursion
function recursion (arguments) {
The following code is the structure part of the control function repeating call.
Gets a new parameter that calls this function again, possibly multiple sets of arguments values.
Corresponds to the condition (variable, arguments) and modify_arguments_variable (arguments, variable) in the loop.
New_arguments:=conditional_get_next (arguments);
For each group of new parameters, call the function itself.
Results:=recursion (new_arguments);

The following code is part of the function that runs every call
Calculated results. Involves previous results, current loop variables, and external variables.
Corresponds to the result:=calculate in the loop (result, variable, extern_variables).
Result:=calculate (arguments, extern_variables);
Result:=combine (result, results);
Affects the external environment of the function, that is, modifying external variables
Changestatus (result, arguments, extern_variables);
return result;
}

By comparing two pieces of code, you can see that loops and recursion have similar compositions, and any loops can be implemented recursively by changing the order and the appropriate transformations. This conversion is easy to see when the program is simple. For example, here's a simple cumulative sum function:
Copy Code code as follows:

Loop
function sum (num) {
var result=1;
while (num>1) {
Result+=num;
num--;
}
return result;
}

The corresponding recursive form:

Copy Code code as follows:

Recursion
function sum2 (num) {
if (num>1) {
Return Num+sum (num-1);
}else{
return 1;
}
}

Conversely, most recursive programs can also be implemented directly by loops. Here is a function to find the GCD form of the loop.
Copy Code code as follows:

function Gcd2 (A, b) {
var temp;
if (a<b) {
Temp=a;
A=b;
B=temp;
}
var c=a%b;
while (c!==0) {
A=b;
B=c;
C=a%b;
}
return b;
}

However, it is not always easy to convert from recursive to circular. Generation of recursive pseudocode the new parameter part of this function is called again

New_arguments:=conditional_get_next (arguments);

More flexible than the corresponding part of the loop. Recursion can be grouped into two classes according to the number of new parameter groups (all the parameters required by the function are one group). The first class is a fixed number of parameter sets, which can be converted to loops, examples of Fibonacci and GCD; the second class is uncertainty about the number of parameter groups--as in traversing a graph or tree, where each point has any adjacent point--the recursion cannot be directly converted to a loop.

Since loops can only do one-dimensional repetition, recursion can traverse a two-dimensional structure. For example, in a tree, a node has its own child node, also has the same sibling nodes, simple one-dimensional loop can not traverse in two directions.

But if we use some kind of data structure in the loop to remember some information about the location of the node, the second kind of recursion can also be implemented in loops.

We then use an example to practice the conclusions of the above observations. HTML5 a new method Getelementsbyclassname (names) for document and element that returns all elements with the given class value. Some browsers, including Firefox3, have supported the method. Let's start with a recursive method to give a weaker version, and then rewrite it in a circular way.
Copy Code code as follows:

var getelementsbyclass={};

Elem for a HtmlElement
Name is a single class name
Returns an array containing the element with the given name in all class attributes under Elem
Getelementsbyclass.recursion1=function (Elem, name) {
var list=[];
function GetElements (EL) {
if (El.className.split ("). IndexOf (name) >-1) {
List.push (EL);
}
For (Var i=0, C=el.children i<c.length; i++) {
GetElements (C[i]);
}
}
GetElements (Elem);
return list;
}

As mentioned earlier, in order to remember the location information of the nodes in the loop, we need a data structure that implements the following methods.

Push (object)//write an object.

Objectpop ()//reads the most recently written object and deletes it from the data structure.

Objectget ()//Read the most recently written object without changing the contents of the data structure.

The stack is just such a LIFO data structure. The array object in JavaScript supports the first two methods, and we add a third method to it.

Use a looping version:
Copy Code code as follows:

GETELEMENTSBYCLASS.LOOP1 = function (elem, name) {
Use a JS array as the basis of a needed stack
var stack = [];
Stack.get = function () {
return stack[stack.length-1];
}

var list = [];
The business logic part. Put the eligible element to the list.
function Testelem (EL) {
if (El.className.split ("). IndexOf (name) >-1) {
List.push (EL);
}
}
Check the root element
Testelem (Elem);
Initialize the stack
Stack.push ({
Pointer:elem,
num:0
});
var parent, num, El;
while (true) {
Parent = Stack.get ();
El = Parent.pointer.children[parent.num];
if (EL) {//enter a deeper layer of the tree
Testelem (EL);
Stack.push ({
Pointer:el,
num:0
});
}
else {//return to the upper layer
if (Stack.pop (). Pointer = = Elem) {
Break
}
else {
Stack.get (). num = 1;
}
}
}

return list;
}

summed up. All loops can be implemented recursively, and all recursion can be implemented in loops. Which method to use, by the specific question which kind of idea is more convenient intuitive and the user's preference decides.

Efficiency

In terms of performance, recursion does not have an advantage over loops. In addition to the overhead of multiple function calls, in some cases, recursive returns can result in unnecessary duplication of computations. Take the recursive program that calculates the Fibonacci sequence as an example. When the nth item A (n) is obtained, each item is recalculated from the first n-2. The smaller the number of items, the more times they are repeated. The number of times that B (i) is calculated for Part I,

B (i) = 1; I=n, n-1

B (i) =b (i+1) +b (i+2); I<n-1

In this way, B (i) forms an interesting inverse Fibonacci sequence. To find A (n):

B (i) =a (n+1-i)

In other terms, if C (i) is the number of additions required for a (i), then there is

C (i) = 0; I=0, 1

C (i) =1+c (i-1) +c (i-1); I>1

Order d (i) =c (i) +1, with

D (i) = 1; I=0, 1

D (i) =d (i-1) +d (i-1)

So d (i) forms a Fibonacci sequence. And it can therefore be concluded that:

C (n) =a (n+1)-1

and a (n) is growing exponentially, and this extra repetition can be very surprising when N is larger. corresponding to the use of the cycle of procedures, there are

B (n) = 1; N is any value

C (n) = 0; N=0, 1

C (n) =n-1; N>1

Therefore, when the n is large, the procedure given in the previous loop will be much faster than the procedure using recursion.

As with the loops in the previous section, this flaw in recursion can be remedied as well. We just need to remember the items that have been calculated, and when we get higher, we can read the previous entries directly. This technique is common in recursion and is called "Storage" (memorization).

The following is a recursive algorithm that uses the storage technique to find Fibonacci sequences.
Copy Code code as follows:

Recursion with memorization
function Fibonacci4 (n) {
var memory = []; Used to store each calculated item
Function calc (n) {
var result, p, q;
if (n < 2) {
Memory[n] = n;
return n;
}
else {
p = memory[n-1]? Memory[n-1]: Calc (n-1);
Q = memory[n-2]? Memory[n-2]: Calc (n-2);
result = p + q;
Memory[n] = result;
return result;
}
}
Return calc (n);
}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.