BST 插入节点传新版本(原痛恨JavaScript每一天 __ 没有指针)
2023年2月2日更新
perform代码上传到GitHub了,新方法比老方法慢,不建议在生产环境使用
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
参考:算法新解