JavaScript implementation and application of data structures and algorithms: Stack/recursion/Hanno (1)

Source: Internet
Author: User

Summary

In this article, I will introduce the basic operations of the data structure Stack and some of its applications.

We will see the application of Stack matching detection in parentheses, expression evaluation, and function call.

Recursion is a special function call. Because recursion is very important and difficult to understand in programming, I will explain my understanding of recursion.

Finally, we will see how Stack and Recursion are used to elegantly solve a classic game: Tower of death.

This article also provides an HTML5 demonstration of expression evaluation and tower of Hanoi.

Stack Introduction

Stack is the Stack, which is defined in Wikipedia:

In computer science, it is a special serial form of data structure. It is special in that it can only be called as a stack top indicator at the end of the chain or serial array) to add the information English: push) and output information English: pop) operation. In addition, the stack can also be completed in the form of a one-dimensional array or a serial link.

According to the definition, we know that there are only three stack operations: push, pop, and top ). In addition, the stack can only manipulate the top elements of the stack, that is, operations can only be performed at one end.

Because the stack has the nature of the First pop-up elements, the stack is also called the structure of the Last In First Out (LIFO, Last In First Out.

Stack operations are very simple. We can use a single list and an array to implement the stack.

However, in JavaScript, Array comes with pop () and push () operations, and we can use Array [Array. length-1] to implement top () operations. Therefore, there is no need to implement another Stack type, which can be expressed in Array.

Application

The features of Stack LIFO make it suitable for solving many practical problems. Below we will discuss three of its applications.

Bracket matching detection

When we write code in the editor, some editors will automatically check whether the brackets match before and after. If they do not match, an error will be reported.

With the LIFO feature of Stack, we can easily implement this function.

The pseudo code of the algorithm is as follows:

 
 
  1. // Create a Stack s
  2. S = new stack ()
  3. // Read characters until they are read
  4. While read to c! = EOF:
  5. // If the character is open brackets such as '(' ['{', etc.
  6. If c is opening:
  7. S. push (c)
  8. // If the character is an ending bracket, such as ') '']''}'
  9. Else if c is closing:
  10. // If the stack is empty or the top element of the stack does not match the opening brackets, an error is returned.
  11. If s is empty or f s. pop () is not correspond to c:
  12. Return error!
  13. // If the last stack is not empty, an error is returned.
  14. If s is not empty:
  15. Return error!
  16. // If no error is returned, return normal
  17. Return OK

The principle of the algorithm is that when we encounter an ending bracket, we always need to find whether the last open bracket matches it. If we cannot find the ending bracket, or if the last open parentheses do not match, an error is returned.

Because we always and only need to find the last element, we will open the brackets into the stack, and when matching, it will go out of the stack.

Due to Stack features, this algorithm is simple and clear and consumes a linear O (n) time complexity ).

Evaluate expressions

The powerful feature of Stack also enables it to be used in expression evaluation.

Suppose an expression: 2 + 4/(3-1)

This expression has three types of symbols:

The calculation algorithm is as follows:

 
 
  1. // Allocate two stacks. ops is the operator stack, and nums is the digital stack.
  2. Ops = new Stack, nums = new Stack
  3. // Read characters from the expression until the end
  4. While read c in expression! = EOF:
  5. // If it is left parenthesis, the input operator Stack
  6. If c is '(':
  7. Ops. push (c)
  8. // If it is a number, add it to the digital stack.
  9. Else if c is a number:
  10. Nums. push (c)
  11. // If it is an operator
  12. Else if c is an operator:
  13. // If the top element of the operator Stack has a higher or the same priority as that of c, a single operation is performed.
  14. While ops. top () is equal or precedence over c:
  15. Op = ops. pop ()
  16. Opn2 = nums. pop ()
  17. Opn1 = nums. pop ()
  18. // Perform a single operation and import the operation count to the digital Stack
  19. Nums. push (cal (op, opn1, opn2 ))
  20. // If it is a right Brace
  21. Else if c is ')':
  22. // Unless the top element of the stack is left parenthesis, the operator stacks out of the stack and adds the calculation result to the digital stack.
  23. Op = ops. pop ()
  24. While op! = '(':
  25. Opn2 = nums. pop ()
  26. Opn1 = nums. pop ()
  27. Nums. push (cal (op, opn1, opn2 ))
  28. Op = ops. pop ()
  29. // Return the stack top element of the digital Stack
  30. Return nums. top ()

The following is a DEMO of expression evaluation:

Function call

When debugging code, we often find the following error messages when encountering function errors:

 
 
  1. /Users/tim/Codes/JavaScript/dsaginjs/DSinJS/Stack/InfixExpression.js:59 
  2.     return prioty[a] ) prioty[b];  
  3.                      ^  
  4. SyntaxError: Unexpected token )  
  5.     at Module._compile (module.js:439:25)  
  6.     at Object.Module._extensions..js (module.js:474:10)  
  7.     at Module.load (module.js:356:32)  
  8.     at Function.Module._load (module.js:312:12)  
  9.     at Function.Module.runMain (module.js:497:10)  
  10.     at startup (node.js:119:16)  
  11.     at node.js:902:3 

In fact, we just got an error in one place. Why do we print so many error messages?

The reason is that the interpreter prints out the stacks of all called functions that reported the error.

When calling a function, we need to switch to the called function, but once the function call ends, we have to return to the original position.

Using the stack, we can implement this in an orderly manner, that is, when the function is called, we put the current function variable and context into the stack, and wait until the function call ends, and then we exit the stack, get the previous context and variable.


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.