关闭

[数据结构]二叉查找树-基础版

标签: 数据结构二叉树指针存储
67人阅读 评论(0) 收藏 举报
分类:

基础信息:(摘自某度百科)
二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)).


废话这么多。


逻辑结构

一棵二叉查找树满足一下几条性质。

对于任意节点:
1、其左子节点的键值小于其自身键值
2、其右子节点的键值大于其自身键值
3、任意节点可以代表一棵二叉查找树

如图即是一棵简单的bst(binary search tree):
简单的bst
根据其性质,我们又能总结出:

一棵bst的左节点的左节点的左节点。。。的左节点(最左节点)带有这棵树中的最小键值
同理,最右节点带有最大键值
一棵树中不允许带有两个相同键值的节点同时存在

由于数组过于占用空间,我打算用指针实现。
首先声明一个节点结构体。一个节点包括:

指向左子节点与右子节点的指针
键值
(可选)查询值
struct node{
    node *lchild,rchild;
    int key,value;
    node (int k,int v){key=k,val=v;}
    node(){}
};

现在我们来构建一棵树。
根据性质:任意节点可代表一棵二叉查找树,我们要实例化一个根节点。

class BST{
    node *root;
public:
};

一个数据结构所具有的基本素养(划掉)操作包括插入和查询操作。于是我们在BST类中添加如下insert()与query()。

class BST{
    node *root;
public:
    void insert(int key,int val);
    int query(int key);
};

具体实现

插入
1、递归版
递归查询的优点是代码量短,但对于刚刚接触递归的童鞋较难理解。
接下来的代码我将逐句解释。

void insert(node &*target,int key,int val){
//一定要注意取址符!!!!!
    if(!target){
        target=new node(key,val);
        return;//递归终止条件,如果当前节点为空,则创建一个新的节点
    }
    //只有对非空节点的访问能够执行到这里
    if(key>target->key)
        insert(target->rchild,key,val);
        //由于待插入键值大于当前结点,所以应该向右子节点插入
    else if(key<target->key)
        insert(target->lchild,key,val);
    else return;//插入的键值已经存在于当前的树中,假设这种情况不存在
}

2、非递归版
如果不用递归,代码会变得复杂一些。

void insert(int key,int val){
    node **scout=&root;
    while(*scout){
        if(key>*scout->key)scout=&(*scout->rchild);
        else scout=&(*scout->lchild);
    }
    *scout=new node(key,val);
}

查询
其实查询操作已经隐含在了插入中。

void query(int key,int val){
    node *scout=root;
    while(scout->key!=key){
        if(key>scout->key)scout=scout->rchild;
        else scout=scout->lchild;
    }
    return scout->val;
}

由于不需要修改节点信息,所以查询操作不需要取址符。
至此,一个二叉查找树诞生了。

class Tree{
    struct node{
        int key,val;
        node(int k,int v){key=k,val=v;}
        node(){}
    };
    node *root;
public:
    void insert(int key,int val){
        node **scout=&root;
        while(*scout){
            if(key>*scout->key)scout=&(*scout->rchild);
            else scout=&(*scout->lchild);
        }
        *scout=new node(key,val);
    }
    void query(int key,int val){
        node *scout=root;
        while(scout->key!=key){
            if(key>scout->key)scout=scout->rchild;
            else scout=scout->lchild;
        }
        return scout->val;
    }
};

实例化后就可以使用了
还可以进一步修改成模板类

template<typename KeyType,typename ValType>
class Tree{
    struct node{
        KeyType key;ValType val;
        node(KeyType k,ValType v){key=k,val=v;}
        node(){}
    };
    node *root;
public:
    void insert(KeyType key,ValType val){
        node **scout=&root;
        while(*scout){
            if(key>*scout->key)scout=&(*scout->rchild);
            else scout=&(*scout->lchild);
        }
        *scout=new node(key,val);
    }
    int query(KeyType key){
        node *scout=root;
        while(scout->key!=key){
            if(key>scout->key)scout=scout->rchild;
            else scout=scout->lchild;
        }
        return scout->val;
    }
};
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:814次
    • 积分:87
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论