Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript二进制搜索树的实现_Javascript_Sorting_B Tree - Fatal编程技术网

javascript二进制搜索树的实现

javascript二进制搜索树的实现,javascript,sorting,b-tree,Javascript,Sorting,B Tree,有谁知道Javascript中简单BTree实现的好例子吗?我有一堆随机到达的“东西”,并希望有效地插入每一个 最终,每个新的节点都将根据其在树中的位置插入DOM 我可以从头开始编写代码,但我不想重新发明任何轮子 谢谢这有帮助吗如果这很重要,我发现将此类数据存储为文字树比将其存储为已排序的数组并在数组上进行二进制搜索以拼接/插入元素的效率要低。显然,JavaScript对象创建不是免费的 还有一个ol“编码数组中的树”技巧: [5, 3, 7, 1, null, 6, 9, null, null

有谁知道Javascript中简单BTree实现的好例子吗?我有一堆随机到达的“东西”,并希望有效地插入每一个

最终,每个新的节点都将根据其在树中的位置插入DOM

我可以从头开始编写代码,但我不想重新发明任何轮子


谢谢这有帮助吗

如果这很重要,我发现将此类数据存储为文字树比将其存储为已排序的数组并在数组上进行二进制搜索以拼接/插入元素的效率要低。显然,JavaScript对象创建不是免费的

还有一个ol“编码数组中的树”技巧:

[5, 3, 7, 1, null, 6, 9, null, null, null, null, null, null] 

      5
     / \
    3   7
   /   / \
  1   6   9
i、 e.儿童(N[i])=N[2i+1],N[2i+2]。我不知道这是否真的能让你在JavaScript中获胜

如果你尝试一些二叉树的替代方法,你能在这里发表你的发现吗?:)

你可以试试,一个javascript库,它有你需要的一切。

函数BinarySearchTree(){
this.root=null;
}
BinarySearchTree.prototype.makeNode=函数(值){
var节点={};
node.value=值;
node.left=null;
node.right=null;
返回节点;
};
BinarySearchTree.prototype.add=函数(值){
var currentNode=this.makeNode(值);
如果(!this.root){
this.root=currentNode;
}否则{
插入(currentNode);
}
归还这个;
};
BinarySearchTree.prototype.insert=函数(currentNode){
var值=currentNode.value;
变量遍历=函数(节点){
//如果值等于节点的值,则忽略
//和退出函数,因为我们不希望重复
if(值===节点值){
返回;
}else if(值>节点值){
如果(!node.right){
node.right=当前节点;
返回;
}否则
遍历(node.right);
}else if(值<节点值){
如果(!node.left){
node.left=当前节点;
返回;
}否则
遍历(节点左);
}
};
遍历(this.root);
};
BinarySearchTree.prototype.contains=函数(值){
var node=this.root;
变量遍历=函数(节点){
如果(!node)返回false;
if(值===节点值){
返回true;
}else if(值>节点值){
返回遍历(node.right);
}else if(值<节点值){
返回遍历(node.left);
}
};
回程导线(节点);
};
/*宽度优先树遍历*/
/*广度优先搜索查找每个级别的所有同级
按从左到右或从右到左的顺序*/
BinarySearchTree.prototype.BroadthFirsttr=函数(){
var node=this.root;
变量队列=[node];
var结果=[];
while(node=queue.shift()){
结果推送(节点值);
node.left&&queue.push(node.left);
node.right&&queue.push(node.right);
}
返回结果;
};
BinarySearchTree.prototype.BroadthFirstRtl=函数(){
var node=this.root;
变量队列=[node];
var结果=[];
while(node=queue.shift()){
结果推送(节点值);
node.right&&queue.push(node.right);
node.left&&queue.push(node.left);
}
返回结果;
};
/*深度优先遍历*/
/*前序是一种深度优先遍历,它尝试
在探索兄弟姐妹之前,在树上走得更深。信息技术
首先返回最浅的子代。
1) 显示根元素(或当前元素)的数据部分
2) 通过递归调用pre-order函数遍历左子树。
3) 通过递归调用pre-order函数遍历右子树*/
BinarySearchTree.prototype.preOrder=函数(){
var结果=[];
var node=this.root;
变量遍历=函数(节点){
结果推送(节点值);
node.left&遍历(node.left);
node.right&遍历(node.right);
};
导线(节点);
返回结果;
};
/*顺序遍历是一种深度优先遍历
在探索兄弟姐妹之前,这也会尝试在树中深入。
然而,它首先返回最深的后代
1) 通过递归调用pre-order函数遍历左子树。
2) 显示根元素(或当前元素)的数据部分
3) 通过递归调用pre-order函数遍历右子树*/
BinarySearchTree.prototype.inOrder=函数(){
var结果=[];
var node=this.root;
变量遍历=函数(节点){
node.left&遍历(node.left);
结果推送(节点值);
node.right&遍历(node.right);
};
导线(节点);
返回结果;
};
/*后序遍历是一种深度优先遍历
在探索兄弟姐妹之前,这也会尝试在树中深入。
然而,它首先返回最深的后代
1) 通过递归调用pre-order函数遍历左子树。
2) 显示根元素(或当前元素)的数据部分
3) 通过递归调用pre-order函数遍历右子树*/
BinarySearchTree.prototype.postOrder=函数(){
var结果=[];
var node=this.root;
变量遍历=函数(节点){
node.left&遍历(node.left);
node.right&遍历(node.right);
结果推送(节点值);
};
导线(节点);
返回结果;
};
//查找最左边的节点以查找二叉树的最小值;
BinarySearchTree.prototype.findMin=函数(){
var node=this.root;
变量遍历=函数(节点){
return!node.left?node.value:遍历(node.left);
};
回程导线(节点);
};
//找到最右边的节点,找到二叉树的最大值;
BinarySearchTree.prototype.fi
function BinarySearchTree() {
    this.root = null;
}

BinarySearchTree.prototype.makeNode = function(value) {
    var node = {};
    node.value = value;
    node.left = null;
    node.right = null;
    return node;
};

BinarySearchTree.prototype.add = function(value) {
    var currentNode = this.makeNode(value);
    if (!this.root) {
        this.root = currentNode;
    } else {
        this.insert(currentNode);
    }
    return this;
};

BinarySearchTree.prototype.insert = function(currentNode) {
    var value = currentNode.value;
    var traverse = function(node) {
        //if value is equal to the value of the node, ignore
        //and exit function since we don't want duplicates
        if (value === node.value) {
            return;
        } else if (value > node.value) {
            if (!node.right) {
                node.right = currentNode;
                return;
            } else
                traverse(node.right);
        } else if (value < node.value) {
            if (!node.left) {
                node.left = currentNode;
                return;
            } else
                traverse(node.left);
        }
    };
    traverse(this.root);
};


BinarySearchTree.prototype.contains = function(value) {
    var node = this.root;
    var traverse = function(node) {
        if (!node) return false;
        if (value === node.value) {
            return true;
        } else if (value > node.value) {
            return traverse(node.right);
        } else if (value < node.value) {
            return traverse(node.left);
        }
    };
    return traverse(node);
};


/* BREADTH FIRST TREE TRAVERSAL */

/* Breadth First Search finds all the siblings at each level
   in order from left to right or from right to left. */

BinarySearchTree.prototype.breadthFirstLTR = function() {
    var node = this.root;
    var queue = [node];
    var result = [];
    while (node = queue.shift()) {
        result.push(node.value);
        node.left && queue.push(node.left);
        node.right && queue.push(node.right);
    }
    return result;
};


BinarySearchTree.prototype.breadthFirstRTL = function() {
    var node = this.root;
    var queue = [node];
    var result = [];
    while (node = queue.shift()) {
        result.push(node.value);
        node.right && queue.push(node.right);
        node.left && queue.push(node.left);
    }
    return result;
};

/*DEPTH FIRST TRAVERSALS*/

/*  preOrder is a type of depth-first traversal that tries 
    togo deeper in the tree before exploring siblings. It 
    returns the shallowest descendants first.

    1) Display the data part of root element (or current element)
    2) Traverse the left subtree by recursively calling the pre-order function.
    3) Traverse the right subtree by recursively calling the pre-order function. */

BinarySearchTree.prototype.preOrder = function() {
    var result = [];
    var node = this.root;
    var traverse = function(node) {
        result.push(node.value);
        node.left && traverse(node.left);
        node.right && traverse(node.right);
    };
    traverse(node);
    return result;
};

/*  inOrder traversal is a type of depth-first traversal
    that also tries to go deeper in the tree before exploring siblings.
    however, it returns the deepest descendents first

    1) Traverse the left subtree by recursively calling the pre-order function.
    2) Display the data part of root element (or current element)
    3) Traverse the right subtree by recursively calling the pre-order function. */

BinarySearchTree.prototype.inOrder = function() {
    var result = [];
    var node = this.root;
    var traverse = function(node) {
        node.left && traverse(node.left);
        result.push(node.value);
        node.right && traverse(node.right);
    };
    traverse(node);
    return result;
};

/*  postOrder traversal is a type of depth-first traversal
    that also tries to go deeper in the tree before exploring siblings.
    however, it returns the deepest descendents first

    1) Traverse the left subtree by recursively calling the pre-order function.
    2) Display the data part of root element (or current element)
    3) Traverse the right subtree by recursively calling the pre-order function. */


BinarySearchTree.prototype.postOrder = function() {
    var result = [];
    var node = this.root;
    var traverse = function(node) {
        node.left && traverse(node.left);
        node.right && traverse(node.right);
        result.push(node.value);
    };
    traverse(node);
    return result;
};

//find the left most node to find the min value of a binary tree;
BinarySearchTree.prototype.findMin = function() {
    var node = this.root;
    var traverse = function(node) {
        return !node.left ? node.value : traverse(node.left);
    };
    return traverse(node);
};

//find the right most node to find the max value of a binary tree;
BinarySearchTree.prototype.findMax = function() {
    var node = this.root;
    var traverse = function(node) {
        return !node.right ? node.value : traverse(node.right);
    };
    return traverse(node);
};


BinarySearchTree.prototype.getDepth = function() {
    var node = this.root;
    var maxDepth = 0;
    var traverse = function(node, depth) {
        if (!node) return null;
        if (node) {
            maxDepth = depth > maxDepth ? depth : maxDepth;
            traverse(node.left, depth + 1);
            traverse(node.right, depth + 1);
        }
    };
    traverse(node, 0);
    return maxDepth;
};


//Can you write me a function that returns all the averages of the nodes 
//at each level (or depth)?? with breadth-first traversal


BinarySearchTree.prototype.nodeAverages = function() {
    var node = this.root;
    var result = {};
    var depthAverages = [];

    var traverse = function(node, depth) {
        if (!node) return null;
        if (node) {
            if (!result[depth])
                result[depth] = [node.value];
            else
                result[depth].push(node.value);
        }
        //check to see if node is a leaf, depth stays the same if it is
        //otherwise increment depth for possible right and left nodes
        if (node.right || node.left) {
            traverse(node.left, depth + 1);
            traverse(node.right, depth + 1);
        }
    };
    traverse(node, 0);

    //get averages and breadthFirst
    for (var key in result) {
        var len = result[key].length;
        var depthAvg = 0;
        for (var i = 0; i < len; i++) {
            depthAvg += result[key][i];
        }
        depthAverages.push(Number((depthAvg / len).toFixed(2)));
    }
    return depthAverages;
};

//Convert a binary search tree to a linked-list in place. 
//In-order depth-first traversal.
function LinkedList() {
    this.head = null;
}

BinarySearchTree.prototype.convertToLinkedList = function() {

    var result = [];
    var node = this.root;
    if (!node) return null;

    var traverse = function(node) {
        node.left && traverse(node.left);
        result.push(node.value);
        node.right && traverse(node.right);
    };

    traverse(node);

    var makeNode = function(value) {
        var node = {};
        node.value = value;
        node.next = null;
        return node;
    };

    var list = new LinkedList();
    list.head = makeNode(result[0]);
    var current = list.head;

    for (var i = 1; i < result.length; i++) {
        var currentNode = makeNode(result[i]);
        current.next = currentNode;
        current = current.next;
    }
    return list;
};

//TESTS

var bst = new BinarySearchTree();
bst.add(40).add(25).add(78).add(10).add(32);
console.log('BS1', bst);

var bst2 = new BinarySearchTree();
bst2.add(10).add(20).add(30).add(5).add(8).add(3).add(9);
console.log('BST2', bst2);
console.log('BREADTHFIRST LTR', bst2.breadthFirstLTR());
console.log('BREADTHFIRST RTL', bst2.breadthFirstRTL());
console.log('PREORDER', bst2.preOrder());
console.log('INORDER', bst2.inOrder());
console.log('POSTORDER', bst2.postOrder());

/* 
BREADTHFIRST LTR [ 10, 5, 20, 3, 8, 30, 9 ]
BREADTHFIRST RTL [ 10, 20, 5, 30, 8, 3, 9 ]
PREORDER [ 10, 5, 3, 8, 9, 20, 30 ]
INORDER [ 3, 5, 8, 9, 10, 20, 30 ]
POSTORDER [ 3, 9, 8, 5, 30, 20, 10 ]
*/

var bst3 = new BinarySearchTree();
bst3.add('j').add('f').add('k').add('z').add('a').add('h').add('d');
console.log(bst3);
console.log('BREADTHFIRST LTR', bst3.breadthFirstLTR());
console.log('BREADTHFIRST RTL', bst3.breadthFirstRTL());
console.log('PREORDER', bst3.preOrder());
console.log('INORDER', bst3.inOrder());
console.log('POSTORDER', bst3.postOrder());

/*
BREADTHFIRST LTR [ 'j', 'f', 'k', 'a', 'h', 'z', 'd' ]
BREADTHFIRST RTL [ 'j', 'k', 'f', 'z', 'h', 'a', 'd' ]
PREORDER [ 'j', 'f', 'a', 'd', 'h', 'k', 'z' ]
INORDER [ 'a', 'd', 'f', 'h', 'j', 'k', 'z' ]
POSTORDER [ 'd', 'a', 'h', 'f', 'z', 'k', 'j' ]
 */


console.log(bst2.findMin()); // 3
console.log(bst2.findMax()); // 30
console.log(bst2.contains(15));
//bst2.add(55);
//bst2.add(65);
//bst3.add(75);
console.log(bst2);
console.log(bst2.getDepth()); // 3
console.log(bst2.add(7).add(50).add(80).add(98));
console.log(bst2.getDepth()); // 5
console.log(bst2.nodeAverages()); //[ 10, 12.5, 13.67, 22, 80, 98 ]

console.log(bst2.convertToLinkedList());
//[ 3, 5, 7, 8, 9, 10, 20, 30, 50, 80, 98 ]
//{ head: { value: 3, next: { value: 5, next: [Object] } } }