谈谈我思考总结的一些算法思想方法

算法依托于数据结构而存在,所以在每种语言中,或多或少,都会有一些专门针对这些数据结构来解决问题的方法。下面就谈一谈我的一些思考。

个人不才,总结了一个小小的公式,算法=数据结构+逻辑+(创新性)

在前端中,使用频率比较高的,应该就是数组,链表,队列,栈,二叉树以及Map和Set结构。

其中呢,由于数组的API很多很强大,在js中经常使用数组的pop和push来模拟栈操作。用数组的shift和push来模拟队列的操作,这很重要。Map和Set结构,可以对数组的某些方向增强(比如数组去重等等) 。思想上以迭代为主。

二叉树和链表呢,是乱序储存在堆中的,由于其都是通过指针来构成链式结构。所以在思想方法上以递归为主。当然,DFS和BFS的非递归调用也可以采用迭代的思想。

所以,在算法中呢,最基础的或许也是最有力量感的就是去体会一下迭代的神奇魅力了。

下面我就用二叉树的前序,中序,后序和层序的递归和非递归(迭代)来实现一下,对比两中基本的思想方法有何不同以及有何相同的。

首先先全局定义一个tree对象。

function TreeNode(val, left, right) {
    this.val = (val===undefined ? 0 : val)
    this.left = (left===undefined ? null : left)
    this.right = (right===undefined ? null : right)
}

前序遍历,二叉树最基本的遍历。

//迭代法,利用数组模拟栈结构
var preorderTraversal = function(root) {
    const result=[]
    const stack=[]
    if(root) stack.push(root)
    while(stack.length){
        const n=stack.pop()
        result.push(n.val)
        if(n.right)stack.push(n.right)
        if(n.left)stack.push(n.left)
    }
    return result
}
//递归法
var preorderTraversal = (root) => {
    let result = []
    var preOrderTraverseNode = (node) => {
        if(node) {
            // 先根节点
            result.push(node.val)
            // 然后遍历左子树
            preOrderTraverseNode(node.left)
            // 再遍历右子树
            preOrderTraverseNode(node.right)
        }
    }
    preOrderTraverseNode(root)
 

 中序遍历。

//迭代法
var inorderTraversal = function(root) {
    const stack = []
    const res = []
    let p = root
    while (stack.length || p) {
        while (p) {
            stack.push(p)
            p = p.left
        }
        const n = stack.pop()
        res.push(n.val)
        p = n.right
    }
    return res
}

//递归法
var inorderTraversal = function(root) {
    let result = [];
    this.inOrder = function(root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        result.push(root.val);
        inOrder(root.right);
    }
    inOrder(root);
    return result;
}

后序遍历。

//非递归的栈思想
var postorderTraversal = function(root) {
    if(!root)return []
    let result=[]
    let stack=[root]
    while(stack.length){
        let n=stack.pop()
        //这一步数组操作很重要
        result.unshift(n.val)
        n.left && stack.push(n.left)
        n.right && stack.push(n.right)
        
    }
    return result
}
//递归法
var postorderTraversal = function(root) {
    const res = [];
    if (!root) return res;
    const postOrder = node => {
        if (!node) return null;
        postOrder(node.left);
        postOrder(node.right);
        res.push(node.val);
    }
    postOrder(root);
    return res;
}

层序遍历。

//迭代法
var levelOrder = function(root) {
    if(!root){
        return []
    }
    let result=[]
    let quene=[root]
    while(quene.length!==0){
        let queneLength=quene.length
        let currentLevel=[]
        for(let i=0;i<queneLength;i++){
            let node=quene.shift()
            currentLevel.push(node.val)
            if(node.left)quene.push(node.left)
            if(node.right)quene.push(node.right)
        }
        result.push(currentLevel)
    }
    return result
}
//递归法
var levelOrder = function (root, depth = 0, res = []) {
    if (!root) {
        return [];
    }
    res[depth] || (res[depth] = []);
    res[depth].push(root.val);
    levelOrder(root.left, depth + 1, res);
    levelOrder(root.right, depth + 1, res);
    return res;
}

可以看到,两大算法思想利器的力量!递归就是结构上简单,思想上复杂,迭代就是思想上简单,结构上复杂?会不会有二者兼得的呢?

以上就是表达我对于算法方面的部分思考。算法可以难得难道无解,知识体系,技巧“绝招”多种多样。如果有小伙伴也感兴趣的可以一起合作探讨啊!!如果有错误或者不当也请指正批评!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值