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

本文介绍了JavaScript中的栈数据结构,包括其抽象数据类型定义、JS实现以及在实际问题中的应用,如进制转换、计算阶乘、括号匹配和后缀表达式解析。栈因其后入先出的特性,在处理这些算法问题时展现出高效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

栈是一种后入先出(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.js
function 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.js
function 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.js
function 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.youkuaiyun.com/gaoxin1076/article/details/7364098

//practice.js
function 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值