BST 插入节点传新版本(原痛恨JavaScript每一天 __ 没有指针)

2023年2月2日更新

perform代码上传到GitHub了,新方法比老方法慢,不建议在生产环境使用

image

GitHub地址:https://github.com/Dou-fugan/webDemo/tree/new-way-building-BST

船新船新版本(2023年10月1)

之前两种方法,思想其实是一致的,在递归函数内部修改自己的值,这样涉及到引用的修改,对于没有指针的语言来说引入了额外的复杂度,我参考了python的版本,不用在函数内部修改传进来的变量,而是将修改后的内容return出去,我认为这种事最好的版本

let node = { val: 1, left: null, right: null };
function insert(node, val) {
  if (!node) return { val, left: null, right: null };
  if (val < node.val) node.left = insert(node.left, val);
  else node.right = insert(node.right, val);
  return node;
}
insert(node, 2);
insert(node, 3);
insert(node, 0);
insert(node, -1);
insert(node, -5);
insert(node, -0.5);
console.log(node);

船新版本(2023年1月30日更新)

数据结构就是很正常的 val,left,right

function* f() {
  let node = {
    ... // 构建代码我粘在改代码片段下面了
  };
  //     3
  //    / \
  //   1   5
  //  /
  // -1
  let phantom = function (node,t) {
    return {
      get () {return node[t] },
      set (x) {return node[t] = x}
    }
  }
  let insert = function (node, v) {
    if (!node.get()) return node.set({ val: v, next: null })
    if (node.get().val < v) insert(phantom(node.get(),'right'), v);
    else insert(phantom(node.get(),'left'), v);
  };
  insert(phantom({left:node},'left'), 2);
  insert(phantom({left:node},'left'), 4);
  yield node.left.right.val === 2;
  yield node.right.left.val === 4;
}
for (const x of f()) {
  console.log(x);
}

树:

let node = {
  val: 3,
  left: {
    val: 1,
    left: {
      val: -1,
      left: null,
      right: null
    },
    right: null
  },
  right: {
    val: 5,
    left: null,
    right: null
  }
};

背景 (原帖从这里开始)

二叉搜索树,插入节点

JavaScript解法

function insertNode(root, newNode) {
    if (newNode.key < root.key) {
        if (root.left) {
            insertNode(root.left, newNode);
        } else {
            root.left = newNode;
        }
    } else {
        if (root.right) {
            insertNode(root.right, newNode);
        } else {
            root.right = newNode;
        }
    }
}

function insert(root, keys) {
    let newNode = new Node(key);
    return insertNode(root, newNode);
}

insert(root, key); // 4, 3, 5, 9, 8, 2, 12, 6

c++ 解法

#include <iostream>
#include <assert.h>
using namespace std;

class Node{
public:
    int val = 0;
    Node* left = NULL;
    Node* right = NULL;
    Node(int v):val(v){}
};
void insert(Node** node,int v) {
    if (!*node) {*node = new Node(v);return;}
    if ((*node)->val > v) insert(&(*node)->left,v);
    else insert(&(*node)->right,v);
}
int main() {
    Node* root = new Node(2);
    root->left = new Node(1);
    root->right = new Node(4);
    root->left->left = new Node(-1);
    insert(&root,0);
    insert(&root,3);
    cout << root->left->left->right->val << endl;
    cout << root->right->left->val << endl;
    return 0;
}

对比总结

c++主体解法只有三行 如果当前节点为空,插入到当前节点,当前节点不为空,根据value大小,递归左子树或右子树
JavaScript的思路是判断左孩子和右孩子,一堆if else 很丑
究其原因: JavaScript没有指针,其他语言也一样,没有指针的语言,比如java

参考:算法新解

posted @ 2023-01-30 23:56  dou_fu_gan  阅读(125)  评论(0编辑  收藏  举报