您现在的位置:首页 >> 前端 >> 内容

二叉树与二叉查找树

时间:2017/9/13 10:33:00 点击:

  核心提示:一、树的相关术语树是一种非线性的数据结构,以分层的形式存储数据 树由一组以边连接的节点组成,如下:树的层数被定义为树的深度二、二叉树二叉树是一种特殊的树,规定每个节点的子节点不能超过两个 通过将子节点...

一、树的相关术语

树是一种非线性的数据结构,以分层的形式存储数据 树由一组以边连接的节点组成,如下:

二叉树与二叉查找树

树的层数被定义为树的深度

二、二叉树

二叉树是一种特殊的树,规定每个节点的子节点不能超过两个 通过将子节点的个数设置为2,可以高效地在树中插入、删除、查找数据 二叉查找树是一种特殊的二叉树,相对较小的值保存在左节点上,较大的值保存在右节点上,这一特性使得查找的效率很高

二叉树与二叉查找树

三、二叉查找树的实现

1、 二叉查找树由节点组成,或者说树都是由节点组成,因此,我们要定义的第一个对象就是Node:

function Node(data){
    this.data = data;   //存储键值
    this.left = left;   //指向左孩子的指针
    this.right = right; //指向右孩子的指针
    this.show = show;   //显示保存在节点中的数据
}
function show(){
    return this.data;
}

2、创建一个类,用来表示二叉查找树(BST)。类中只包含一个数据成员:root(一个用来表示二叉查找树的根节点的Node对象),初始化为null,从而创建一个空节点。

function BST (){
    this.root = null;
}

3、设计一个insert()方法,用来向树中加入新节点

创建一个Node对象,将数据传入该对象中保存 检查BST是否有根节点,如果没有,是一颗新树,该节点为树的根节点 如果该元素不是树的根节点,则要遍历BST,找到适合插入节点的位置,实现算法:
设根节点为当前节点 如果待插入节点中保存的数据小于当前节点,则设新的当前节点为原节点的左节点,否则,执行第四步 如果当前节点为null,则插入节点,否则,继续循环第二步 如果待插入节点中保存的数据大于当前节点,则设新的当前节点为原节点的右节点 如果当前节点为null,则插入节点,否则,继续循环否则,继续循环第四步
function BST() {
    this.root = null;
    this.insert = insert;
}

function insert(data) {
    var node = new Node(data,null,null);
    if(this.root == null) {
        this.root = node;
    } else {
        var currentNode = this.root;
        var parent;
        while(true) {
            parent = currentNode;
            if(data < currentNode.data) {
                currentNode = currentNode.left;
                if(currentNode == null) {
                    parent.left = node;
                    break;
                }
            } else {
                currentNode = currentNode.right;
                if(currentNode == null) {
                    parent.left = node;
                    break;
                }
            }
        }
    }
}

4、二叉查找树的遍历

遍历有三种方式
(1)中序遍历:按照节点上的键值,以升序访问BST上的所有节点

二叉树与二叉查找树

function inOrder(node){
    if( node != null){
        inOrder(node.left);
        console.log(node.show()+' ');
        inOrder(node.right)
    }
}

(2) 先序遍历:先访问根节点,然后以同样的方式访问左子树和右子树
二叉树与二叉查找树

function preOrder(node){
    if(node != null){
        console.log(node.show());
        preOrder(node.left);
        preOrder(node.right)
    }
}

(3) 后序遍历:先访问叶子节点,从左子树到右子树再到根节点
二叉树与二叉查找树

function postOrder(node){
    if(node != null){
        postOrder(node.left);
        postOrder(node.right);
        console.log(node.show());
    }
}
测试程序
var nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);

console.log("inOrder:")
inOrder(nums.root); //3 16  22  23  37  45  99
console.log("preOrder")
preOrder(nums.root); //23 16  3  22  45  37  99
console.log("postOrder")
postOrder(nums.root); //3  22  16  37  99  45  23

四、在二叉查找树上进行查找
1、查找最小值和最大值

查找最小值:因为较小的值总是在左节点上,因此,在BST上要找到最小值,只需要遍历左子树,直到最后一个节点
function getMin(){
    var node = this.root;
    var parent;
    while(node != null){
        parent = node;
        node = node.left;
    }
    return parent.data;
}
查找最大值:因为较大的值总是在右节点上,因此,在BST上要找到最大值,只需要遍历右子树,直到最后一个节点
function getMax(){
    var node = this.root;
    var parent;
    while(node != null){
        parent = node;
        node = node.right;
    }
    return parent.data;
}
使用上面的测试数据进行测试
console.log(nums.getMax());     //99
console.log(nums.getMin());     //3

2、查找给定值

在BST上要查找给定值,需要比较该值和当前节点上的值的大小。 通过比较,确定给定值不在当前节点时,该向左还是向右遍历。
function find(data){
    var node = this.root;
    while(node != null){
        if(node.data == data){
            return node;
        }else if(node.data > data){
            node = node.left;
        }else{
            node = node.right;
        }
    }
    return null;
}
找到返回保存该值的节点,没有找到返回null 继续使用上面的测试数据进行测试
console.log(nums.find("23"));
console.log(nums.find("100"));

二叉树与二叉查找树

作者:网络 来源:骑着毛驴的小猴子