设为首页 加入收藏

TOP

javascript实现二叉搜索树(二)
2019-09-19 11:11:22 】 浏览:101
Tags:javascript 实现 搜索
34 inorderTraversal(root.lchild, arr); 35 arr.push(root.key); 36 inorderTraversal(root.rchild, arr); 37 }; 38 39 // 用于先序遍历的递归函数 40 let preOrderTraversal = function (root, arr) { 41 if (!root) return; 42 arr.push(root.key); 43 preOrderTraversal(root.lchild, arr); 44 preOrderTraversal(root.rchild, arr); 45 }; 46 47 // 用于后续遍历的递归函数 48 let lastOrderTraversal = function (root, arr) { 49 if (!root) return; 50 lastOrderTraversal(root.lchild, arr); 51 lastOrderTraversal(root.rchild, arr); 52 arr.push(root.key); 53 }; 54 55 // 二叉搜索树类 56 return class { 57 constructor() { 58 this[ROOT] = null; 59 } 60 61 // 插入 62 insert(key) { 63 let node = new BTNode(key); 64 let root = this[ROOT]; 65 if (!root) { 66 this[ROOT] = node; 67 return; 68 } 69 // 递归插入 70 recursionInsert(root, node); 71 } 72 73 74 // 中序遍历二叉树 75 inorderTraversal() { 76 let arr = []; 77 inorderTraversal(this[ROOT], arr); 78 return arr; 79 } 80 81 // 先序遍历二叉树 82 preOrderTraversal() { 83 let arr = []; 84 preOrderTraversal(this[ROOT], arr); 85 return arr; 86 } 87 88 // 后续遍历 89 lastOrderTraversal() { 90 let arr = []; 91 lastOrderTraversal(this[ROOT], arr); 92 return arr; 93 } 94 } 95 96 })(); 97 98 99 let bst = new BST(); 100 101 bst.insert(20); 102 bst.insert(15); 103 bst.insert(7); 104 bst.insert(40); 105 bst.insert(30); 106 bst.insert(45); 107 bst.insert(50); 108 109 110 console.log(bst); 111 112 113 let a = bst.inorderTraversal(); 114 let b = bst.preOrderTraversal(); 115 let c = bst.lastOrderTraversal(); 116 117 console.log(a); 118 console.log(b); 119 console.log(c);

 

广度优先遍历

// 广度优先遍历
breadthRirstSearch() {
    // 初始化用于广度优先遍历的队列
    let queue = new Queue();
    console.log('根节点', this[ROOT]);

    let arr = [];
    let root = this[ROOT];
    if (!root) return;

    queue.enqueue(root);

    while (queue.size()) {
        let queueFirst = queue.dequeue();
        arr.push(queueFirst.key);
        queueFirst.lchild && queue.enqueue(queueFirst.lchild);
        queueFirst.rchild && queue.enqueue(queueFirst.rchild);
    }

    return arr;
}

 

 

二叉树遍历算法的改进

上面介绍的二傻叔的深度优先遍历算法都是用递归函数实现的,这是很低效的,原因就在于系统帮你调用了一个栈并做了诸如保护现场和恢复现场等复杂的操作,才使得遍历可以用非常简洁的代码实现。

有的人可能会想到,关于二叉树深度优先遍历算法的非递归实现和递归实现,一个是用户自己定义栈,一个是系统栈,为什么用户自己定义的栈要比系统栈执行高效?
一个较为通俗的解释是:递归函数所申请的系统栈,是一个所有递归函数都通用的栈,对于二叉树深度优先遍历算法,系统栈除了记录访问过的节点信息之外,还有其他信息需要记录,以实现函数的递归调用,用户自己定义的栈仅保存了遍历所需的节点信息,是对遍历算法的一个针对性的设计,对于遍历算法来说,显然要比递归函数通用的系统栈更高,也就是一般情况下,专业的要比通用的要好一些。


然而在实际应用中不是这样的,如尾递归在很多机器上都会被优化为循环,因此递归函数不一定就比非递归函数执行效率低。

 

栈数据结构,满足后进先出的规则用来辅佐我们遍历

// 栈结构 用来辅助非递归遍历
class Stack {
  constructor() {
    this.items = [];
  }
  push(data) {
    this.items.push(data);
  }
  pop() {
    return this.items.pop();
  }
  peek() {
    return this.items[this.items.length - 1];
  }
  size() {
    return this.items.length;
  }
}

非递归的先序遍历

preOrderTraversal() {
    console.log('先序遍历');
    let root = this[ROOT];
    // 初始化辅助遍历存储的栈
    let stack = new Stack();

    let arr = []; // 用于存储先序遍历的顺序

    stack.push(root);

    // 如果栈不为空 则一直走
    while (stack.size()) {
        let stackTop = stack.pop();

        // 访问栈顶元素
        arr.push(stackTop.key);
        stackTop.rchild && stack.push(stackTop.rchild);
        stackTop.lchild && stack.push(stackTop.lchild);
    }

    return arr;
}

 

 非递归的中序排

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇js vue 页面添加水印 下一篇vue 实现模糊检索,并根据其他字..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目