Stack (stack) aka stacks, it is a five-color platform rental (www.1159880099.com) QQ1159880099 operation constrained linear table. The limitation is that only one end of the table is allowed to insert and delete operations. This end is called the top of the stack, and the opposite end is called the bottom of the stack.
First, implement a stack class stack
Stack-based features can be used to store arrays of linear tables.
The structure of the initialization stack class is as follows:
function Stack () {
This.space = [];
}
Stack.prototype = {
Constructor:stack,
/ Interface Code /
};
Next, in the prototype, on the stack, out of the stack, empty stack, read the top of the stack, read the entire stack of data on the implementation of the interface.
The Stack class defaults to the array head as the bottom of the stack, the tail to do the top.
1.1 Push-to-stack
The stack can use the push method of the JS array to press the data into the end of the array.
Stack.prototype = {
Push:function (value) {
return This.space.push (value);
}
}
1.2 Pop out of stack
The stack also uses the Pop method of the JS array to eject the data at the tail of the array.
Stack.prototype = {
Pop:function () {
return This.space.pop ();
}
}
1.3 Empty Stack Clear
Emptying the stack is relatively straightforward and resets the array of stored data to an empty array.
Stack.prototype = {
Clear:function () {
This.space = [];
}
}
1.4 Reading Stack Top readtop
Read the top data of the stack and get it by array subscript. One benefit is that the return value is undefined when the subscript is outside the array's valid range.
Stack.prototype = {
Readtop:function () {
return this.space[this.space.length-1];
}
}
1.4 Reading the entire stack read
Reads the entire stack data and returns the current array directly.
Stack.prototype = {
Read:function () {
return this.space;
}
}
1.5 Aggregation
Finally, after aggregating all the features, as shown below, a stack of data structures is done.
function Stack () {
This.space = [];
}
Stack.prototype = {
Constructor:stack,
Push:function (value) {
return This.space.push (value);
},
Pop:function () {
return This.space.pop ();
},
Clear:function () {
This.space = [];
},
Readtop:function () {
return this.space[this.space.length-1];
},
Read:function () {
return this.space;
}
};
Second, actual combat
Data structures and algorithms are designed for better and more efficient solution to engineering problems.
Here to learn, to provide a few real cases, to realize the charm of the data structure and algorithm:)
2.1 Implementation of array reverse
In the current case, the stack will be used to implement the inverse function of the array.
function reverse (arr) {
var arrstack = new Stack ();
for(var i = arr.length - 1; i >= 0; i--){ ArrStack.push(arr[i]);}return ArrStack.read();
}
As shown in the code, it can be divided into the following steps:
Instantiate a stack for storing data
The incoming array is traversed in reverse, and is pressed into the stack one by one
Finally, using the read interface, the output data
It seems very simple, don't worry, complicated in the back:)
2.2 Decimal conversion to Binary
The problem of numerical conversion is the small test sledgehammer of the stack.
Before explaining the conversion method, let's look at a small example:
Converts a decimal 13 to a binary
2 | 13 1  ̄ ̄ ̄2 | 6 0  ̄ ̄ ̄2 | 3 1  ̄ ̄ ̄ ̄ 1 1
As shown above: 13 of the binary code is 1101.
will be converted manually into a stack of storage, only the results of 2 of the remainder of the stack is pressed to save, and finally invert the output.
function binary (number) {
var tmp = number;
var arrstack = new Stack ();
if(number === 0){ return 0;}while(tmp){ ArrStack.push(tmp % 2); tmp = parseInt(tmp / 2, 10);}return reverse(ArrStack.read()).join(‘‘);
}
Binary (14); Output = "1110"
Binary (1024); Output = "10000000000"
2.3 Expression Evaluation
This case, in fact, can be understood as a simplified version of the Eval method.
The case content is the evaluation of 1+7* (4-2).
Before entering the subject, it is necessary to understand the following mathematical theories:
Infix notation (or infix notation) is a general method of arithmetic or logical formula representation, in which the operator is in the middle of the operand in infix form (example: 3 + 4).
The inverse Polish notation (Reverse Polish notation,rpn, or inverse Polish notation) is a mathematical expression introduced by the Polish mathematician Łukasiewicz 1920, in inverse Polish notation, where all operators are placed behind the operands and are therefore also referred to as suffix notation. Inverse Polish notation does not require parentheses to identify the precedence of an operator.
"3-4 + 5" of conventional infix notation "3 4-5 +" in inverse polish notation
The Dispatch-field algorithm (shunting Yard algorithm) is a classical algorithm used to convert infix expressions to suffix expressions, introduced by Edsger Dijkstra, which is named for its operation similar to the train marshalling field.
In advance, this is just the simple version of the implementation. So there are two rules:
Numeric requirements are integers
Do not allow extra spaces in an expression
The implementation code is as follows:
function Calculate (exp) {
var valuestack = new Stack (); Value stack
var operatorstack = new Stack (); operator Stack
var Exparr = Exp.split ("); Cutting string expressions
var first_operator = [' + ', '-']; Add and Subtract operators
var second_operator = [' * ', '/']; Multiplication operator
var special_operator = [' (', ') ']; Brackets
var tmp; Temporarily stores the currently processed characters
var tmpoperator; Temporarily stores the current operator
Traverse expression for (var i = 0, len = exparr.length; i < Len; i++) {tmp = Exparr[i]; Switch (TMP) {case ' (': Operatorstack.push (TMP); Break Case ') '://encounters a closing parenthesis, first out the data while in parentheses ((Tmpoperator = Operatorstack.pop ())!== ' (' && typeof tmpoperator!== ' undefined ') {Valuestack.push (calculator, Tmpoperator (), Value Stack.pop ())); } break; Case ' + ': Case '-': while (typeof Operatorstack.readtop ()!== ' undefined ' && SPE Cial_operator.indexof (Operatorstack.readtop ()) = = = 1 && (Second_operator.indexof (Operatorstack.rea Dtop ())!==-1 | | TMP! = Operatorstack.readtop ())) {//stack top is multiplication or the same priority operation, first out of Stack Valuestack.push (calculator (OperatorS Tack.pop (), Valuestack.pop (), Valuestack.pop ())); } operatorstack.push (TMP); Break Case ' * ': CASe '/': while (typeof operatorstack.readtop ()! = ' undefined ' && first_operator.indexof ( Operatorstack.readtop ()) = = = 1 && special_operator.indexof (operatorstack.readtop ()) = = = 1 && Amp TMP! = Operatorstack.readtop ()) {//stack top for the same priority operation, first out of Stack Valuestack.push (calculator (operatorstack. Pop (), Valuestack.pop (), Valuestack.pop ())); } operatorstack.push (TMP); Break Default:valueStack.push (TMP); }}//handles data in the stack while (typeof (Tmpoperator = Operatorstack.pop ())!== ' undefined ') {Valuestack.push (Calculator (tmpoperator), Valuestack.pop (), Valuestack.pop ()));} return Valuestack.pop (); The results of the calculation are rolled out/* @param operator operator @param initiativenum Active value @param passivitynum passive value */function Calculator (operator, Passivitynum, Initiativenum) {var result = 0; Initiativenum = typeof Initiativenum = = = ' undefined '? 0:parseint (Initiativenum, 10); Passivitynum = typeof Passivitynum = = = ' undefined '? 0:parseint (Passivitynum, 10); Switch (operator) {case ' + ': result = Initiativenum + passivitynum; Console.log (' ${initiativenum} + ${passivitynum} = ${result} '); Break Case '-': result = Initiativenum-passivitynum; Console.log (' ${initiativenum}-${passivitynum} = ${result} '); Break Case ' * ': result = Initiativenum * passivitynum; Console.log (' ${initiativenum} * ${passivitynum} = ${result} '); Break Case '/': result = Initiativenum/passivitynum; Console.log (' ${initiativenum}/${passivitynum} = ${result} '); Break Default:; } return result;
}
Implementation ideas:
Using the Scheduling field algorithm, the infix expression is read and the result is calculated rationally.
The critical point is determined using operatorstack.readtop ()!== ' undefined '. Some books use the # to make the end sign, personally feel a little cumbersome.
Splits a string expression with split and then iterates through the stack. Have to calculate the results in advance, to carry out the corresponding stack processing.
The method of calculating partial results is encapsulated as an independent method calculator. Because the number before and after the multiplication operator is different in operation, it is not possible to swap positions at random.
2.4 infix expression converted to suffix expression (inverse polish notation)
Inverse Polish notation, is a computer-friendly notation that does not require the use of parentheses.
The following case is a workaround for the previous case, and also a dispatch-field algorithm that converts infix expressions to suffix expressions.
function RPN (exp) {
var valuestack = new Stack (); Value stack
var operatorstack = new Stack (); operator Stack
var Exparr = Exp.split (");
var first_operator = [' + ', '-'];
var second_operator = [' * ', '/'];
var special_operator = [' (', ') '];
var tmp;
var tmpoperator;
for (var i = 0, len = exparr.length; i < Len; i++) {tmp = Exparr[i]; Switch (TMP) {case ' (': Operatorstack.push (TMP); Break Case ') '://encounters a closing parenthesis, first out the data while in parentheses ((Tmpoperator = Operatorstack.pop ())!== ' (' && typeof tmpoperator!== ' undefined ') {Valuestack.push (Translate, Tmpoperator (), ValueS Tack.pop ())); } break; Case ' + ': Case '-': while (typeof Operatorstack.readtop ()!== ' undefined ' && SPE Cial_operator.indexof (Operatorstack.readtop ()) = = = 1 && (Second_operator.indexof (Operatorstack.rea Dtop ())!==-1 | | TMP! = Operatorstack.readtop ())) {//stack top is multiplication or the same priority operation, first out of stack Valuestack.push (translate (operatorst Ack.pop (), Valuestack.pop (), Valuestack.pop ())); } operatorstack.push (TMP); Break Case ' * ': Case '/': while (typeof operatorstack.readtop ()! = ' undefined ' && first_operator.indexof (operatorst Ack.readtop ()) = = = 1 && special_operator.indexof (operatorstack.readtop ()) = = = 1 && TMP! = Operatorstack.readtop ()) {//stack top for the same priority operation, first out of stack Valuestack.push (translate (oper Atorstack.pop (), Valuestack.pop (), Valuestack.pop ())); } operatorstack.push (TMP); Break Default:valueStack.push (TMP); }}while (typeof (Tmpoperator = Operatorstack.pop ())!== ' undefined ') {Valuestack.push (Translate (Tmpoperator, VALUESTAC K.pop (), Valuestack.pop ()));} return Valuestack.pop (); The results of the calculation are rolled out/* @param operator operator @param initiativenum Active value @param passivitynum passive value */function translate (operator, p Assivitynum, Initiativenum) {var result = '; Switch (operator) {case ' + ': result = ' ${initiativenum} ${passivitynum} + '; ConsolE.log (' ${initiativenum} + ${passivitynum} = ${result} '); Break Case '-': result = ' ${initiativenum} ${passivitynum}-'; Console.log (' ${initiativenum}-${passivitynum} = ${result} '); Break Case ' * ': result = ' ${initiativenum} ${passivitynum} '; Console.log (' ${initiativenum} * ${passivitynum} = ${result} '); Break Case '/': result = ' ${initiativenum} ${passivitynum}/'; Console.log (' ${initiativenum}/${passivitynum} = ${result} '); Break Default:; } return result;
}
RPN (' 1+7(4-2) ');//output = "1 7 4 2- +"
2.5 Connaught Tower
Hanoi
Hanoi (RTHK: Hanoi) is a mathematical problem formed according to a legend:
There are three Poles a,b,c. A rod has N (n>1) perforated discs, the size of the disk from bottom to top in turn smaller. The following rules are required to move all discs to the C-bar:
Only one disk can be moved at a time;
The market cannot be stacked on a small plate.
Movement of the Hanoi of 4 discs
The classic algorithm application of the stack, the first push is Hanoi.
To understand this algorithm, pay attention to the following points:
Do not delve into every move, abstract understanding
Step one: All non-compliant disks, move from tower A to Tower B cache
Step two: Move the matching disk to Tower C
Step three: Move all B-tower buffers to Tower C
Here is the code implementation:
var atower = new Stack (); Tower A
var btower = new Stack (); Tower B
var ctower = new Stack (); C Tower (Target tower)
var TIER = 4; Number of layers
for (var i = TIER; i > 0; i--) {
Atower.push (i);
}
function Hanoi (n, from, to, buffer) {
if (n > 0) {
Hanoi (n-1, from, buffer, to); All non-conforming disks (n-1), moving from tower A to Tower B cache
To.push (From.pop ()); Move the compliant disk (n) to Tower C
Hanoi (n-1, buffer, to, from); Move all B-tower buffers to Tower C.
}
}
Hanoi (Atower.read (). Length, Atower, Ctower, btower);
The focus of Hanoi, or by recursion to achieve. Put a big problem through recursion and keep splitting up for smaller problems. Then, focus on solving small problems.
Stack application--using JavaScript to describe a five-point color platform rental data structure