Javascript数据结构算法之栈(进制转换,阶乘,后缀表达式,括号匹配)

来源:互联网 发布:淘宝上货助手 编辑:程序博客网 时间:2024/06/10 21:55

栈是一种后入先出(LIFO)的数据结构,数据只能在栈顶添加或者删除,所以操作很快,容易实现。将从3个方面来深入理解和使用栈这种数据结构。

  • 抽象数据类型定义
  • 栈的JS实现
  • 解决实际问题

抽象数据类型定义

属性及方法 作用 push() 入栈 pop() 出栈 peek() 显示栈顶元素 dataStore 存储数据 top 记录栈的长度和位置

栈的JS实现

使用构造器调用模式,这是一套类似类的对象构建语法,通过在函数前面加上new调用,同时this会绑定到这个新对象上。

//Stack.js//Stack对象定义function Stack(){    this.dataStore = [];    this.pop = pop;    this.push = push;    this.peek = peek;    this.clear = clear;    this.length = length;    this.top = 0;}function push(element){    this.dataStore[this.top++] = element;}function pop(){    return this.dataStore[--this.top]}function peek(){    return this.dataStore[this.top-1]}function length(){    return this.top;}function clear(){    this.top = 0;}//实例化Stack对象var oneStack = new Stack();

栈的实际应用

(一)网页展示

这里写图片描述

(二)html代码

<!DOCTYPE html><html><head>    <title>JS structure - Stack</title>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <script src="stack.js" type="text/javascript"></script>    <script src="practice.js" type="text/javascript"></script></head><style>div {    width: 60%;    margin: 30px auto;    padding: 10px;    border: 1px solid #333;}</style><body>    <div>        <h2>进制转换</h2>        <form>            <label for="input_number">输入一个数字:</label>            <input type="text" id="input_number" />            <label for="input_radix">输入进制:</label>            <input type="text" id="input_radix" />            <input type="button" value="转换" onClick="transfer()">            <textarea id="transfer_result"></textarea>        </form>    </div>    ……</body></html>

(三)Javascript方法

1. 进制转换

//practice.jsfunction mulBase(num, base){    var tStack = new Stack();    do{        tStack.push(num%base);//最高位为n%b        num = Math.floor(num / base);//n/b代替n    }while(num > 0);    var converted = "";    while(tStack.length()>0){        converted += tStack.pop();//FILO    }    return converted;}

2. 阶乘

//practice.jsfunction fact(number){    var fStack = new Stack();    while(number > 0)    {        fStack.push(number);//将数字从大到小压入栈中        number = number -1;    }    var result = 1;    while(fStack.length()>0)    {        result *= fStack.pop();//弹出的元素挨个出栈相乘    }    return result;}

3. 括号匹配

//practice.jsfunction bracketmatch(expression){    var bStack = new Stack();    for(var i=0; i<expression.length; i++)    {        if(expression[i] == "(")        {            bStack.push(expression[i]);//遇到“(”将其压入栈出        }        else if(expression[i] == ")")        {            if(bStack.peek() == "(")                bStack.pop();//直到遇到“)”,将“("弹出栈        }        else        {            //其他符号,不进行任何操作        }    }    if(bStack.length()>0)        return false;    else        return true;}

4. 后缀表达式

将中缀表达式转换成后缀表达式的算法思路,可以参看Miibotree的数据结构文,http://blog.csdn.net/gaoxin1076/article/details/7364098

//practice.jsfunction expressionChange(expression){    var result = "";    var operators = new Stack();    for(var i=0; i<expression.length; i++)    {        var currentCharac = expression[i];        switch(currentCharac)        {            case "("://左括号直接入栈                operators.push(currentCharac);                break;            case ")"://右括号将所有栈内元素弹出                while(operators.peek()!="(")                {                    result += operators.pop()+" ";                }                operators.pop();//弹出左括号                break;            case "+":            case "-"://因为+和-的优先级最低,将所有栈内元素弹出后,将当前符号压入栈。                while(operators.length()>0 && operators.peek() != "(")                {                    result += operators.pop()+" ";                }                operators.push(currentCharac);                break;            case "/":            case "*"://只有当栈顶元素是/,*的时候,才需要弹出所有栈内元素。                while(operators.length()>0 && (operators.peek() == "*" || operators.peek() == "/"))                {                    result += operators.pop()+" ";                }                operators.push(currentCharac);                break;            default:                while(currentCharac<="9" && currentCharac>="0")                {                    result += currentCharac;                    currentCharac = expression[++i];                }                result += " ";                i--;//一定要减,不然的话i加了两次1                break;          }    }    while(operators.length()>0)//最后要将站内剩下元素弹出    {        result += operators.pop()+" ";    }    return result;}
1 0