javascript 二叉树(附代码)

前言

最近关注了下扫描线算法,有涉及二叉树的地方,故找了点资料,用js实现了部分功能。


关于二叉树

偷懒直接链接 维基百科 | 百度百科


完整实现代码

(function (w) {
  // 树总集
  let rootTree;

  const binaryTree = (array = []) => {
    return new BinaryTree(array);
  }

  // 空树构造函数
  const Tree = function () {
    // this.value;
    // this.leftTree;
    // this.rightTree;
  }

  /**
   * 
   * 二叉树构造函数
   * @param {array} array
   */
  const BinaryTree = function (array) {
    init(array);
  }

  BinaryTree.prototype = {
    // 树总集
    get rootTree () {
      return rootTree;
    }
  }
  
  // 插值
  BinaryTree.prototype.add = function (value) {
    addValue(value);
  }

  // 查询
  BinaryTree.prototype.has = function (value) {
    return hasValue(value);
  } 

  // 最小值
  BinaryTree.prototype.min = function () {
    return minTree().value;
  }

  // 最大值
  BinaryTree.prototype.max = function () {
    return maxTree().value;
  }

  // 删除
  BinaryTree.prototype.delete = function (value) {
    return deleteValue(value);
  }

  // 清空
  BinaryTree.prototype.clear = function () {
    rootTree = new Tree();
  }

  // 前序
  BinaryTree.prototype.preorderTraversal = function () {
    return preorderTraversalRecursion();
  }

  // 中序
  BinaryTree.prototype.inorderTraversal = function () {
    return inorderTraversalRecursion();
  }

  // 后序
  BinaryTree.prototype.postorderTraversal = function () {
    return postorderTraversalRecursion();
  }

  const init = (array = []) => {
    rootTree = new Tree();
    array.forEach(v => addValue(v));
  }

  const addValue = (v, tree = rootTree) => {
    if (tree.value === undefined) {
      tree.value = v;
    } else if (v < tree.value) {
      if (tree.leftTree === undefined) {
        tree.leftTree = new Tree();
      }
      addValue(v, tree.leftTree);
    } else if (v > tree.value) {
      if (tree.rightTree === undefined) {
        tree.rightTree = new Tree();
      }
      addValue(v, tree.rightTree);
    }
  }

  const hasValue = (v, tree = rootTree) => {
    if (v === tree.value) return true;
    if (v < tree.value && tree.leftTree) return hasValue(v, tree.leftTree);
    else if (v > tree.value && tree.rightTree) return hasValue(v, tree.rightTree);
    return false;
  }

  const minTree = (tree = rootTree) => {
    if (tree.leftTree) {
      return minTree(tree.leftTree);
    }
    return tree;
  }

  const maxTree = (tree = rootTree) => {
    if (tree.rightTree) {
      return maxTree(tree.rightTree);
    }
    return tree;
  }

  const deleteValue = (v, tree = rootTree) => {
    if (v === tree.value) return promotionTree(tree);
    else if (v < tree.value && tree.leftTree) return deleteValue(v, tree.leftTree);
    else if (v > tree.value && tree.rightTree) return deleteValue(v, tree.rightTree);

    // 没有匹配到
    return false;
  }

  const promotionTree = tree => {
    let tempTree;

    if (tree.rightTree) {
      tempTree = minTree(tree.rightTree);
    } else if (tree.leftTree) {
      tempTree = minTree(tree.leftTree);
    } else {
      delete tree.value;
      return true;
    }
    tree.value = tempTree.value;
    return promotionTree(tempTree);
  }

  // 前序遍历
  const preorderTraversalRecursion = (tree = rootTree, result = []) => {
    if (tree.value !== undefined) result.push(tree.value);
    if (tree.leftTree) preorderTraversalRecursion(tree.leftTree, result);
    if (tree.rightTree) preorderTraversalRecursion(tree.rightTree, result);
    return result;
  }

  // 中序遍历
  const inorderTraversalRecursion = (tree = rootTree, result = []) => {
    if (tree.leftTree) inorderTraversalRecursion(tree.leftTree, result);
    if (tree.value !== undefined) result.push(tree.value);
    if (tree.rightTree) inorderTraversalRecursion(tree.rightTree, result);
    return result
  }

  // 后序遍历
  const postorderTraversalRecursion = (tree = rootTree, result = []) => {
    if (tree.leftTree) postorderTraversalRecursion(tree.leftTree, result);
    if (tree.rightTree) postorderTraversalRecursion(tree.rightTree, result);
    if (tree.value !== undefined) result.push(tree.value);
    return result
  }

  w.bt = w.binarytree = binaryTree;
})(window);


代码使用说明

创建二叉树

	const arr = [8,55,0,12,1,2,33];
    // 实例化
    const bt = binarytree(arr);

	// 打印二叉树总集
	console.log(bt.rootTree)
	// 结果
	{
		value: 8,
		leftTree: {
			value: 0,
			rightTree: {
				value: 1,
				rightTree: {
					value: 2,
				},
			},
		},
		rightTree: {
			value: 55,
			leftTree: {
				value: 12,
				rightTree: {
					value: 33,
				},
			},
		}
	}

插值

	const temp = [222,566,-12];
    // 实例化
    const bt = binarytree(arr);
    // 插值
    temp.forEach(v => bt.add(v));

	// 打印二叉树总集
	console.log(bt.rootTree)
	// 结果
	{
		value: 8,
		leftTree: {
			value: 0,
			leftTree: {
				value: -12,
			},
			rightTree: {
				value: 1,
				rightTree: {
					value: 2,
				},
			},
		},
		rightTree: {
			value: 55,
			leftTree: {
				value: 12,
				rightTree: {
					value: 33,
				},
			},
			rightTree: {
				value: 222,
				rightTree: {
					value: 566,
				},
			},
		}
	}

删除操作

	// 删除
	bt.delete(0)
    bt.delete(8)

	// 打印二叉树总集
	console.log(bt.rootTree)
	// 结果
	{
		value: 12,
		leftTree: {
			value: 1,
			leftTree: {
				value: -12,
			},
			rightTree: {
				value: 2,
			},
		},
		rightTree: {
			value: 55,
			leftTree: {
				value: 33,
			},
			rightTree: {
				value: 222,
				rightTree: {
					value: 566,
				},
			},
		}
	}

查询、最大、最小

	bt.has(33);     // true
    bt.has(0)		// false
    
    bt.min()		// -12
    bt.max()		// 556

前序、中序、后序

	// 前序
    console.log(bt.preorderTraversal());
    // 结果 [12, 1, -12, 2, 55, 33, 222, 566]
    
    // 中序
    console.log(bt.inorderTraversal());
    // 结果 [-12, 1, 2, 12, 33, 55, 222, 566]
    
    // 中序
    console.log(bt.postorderTraversal());
    // 结果 [-12, 2, 1, 33, 566, 222, 55, 12]

清空

	bt.clear();
	
	// 打印二叉树总集
	console.log(bt.rootTree)
	// 结果为空树 {}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值