二叉搜索树

来源:互联网 发布:浙师大网络继续教育 编辑:程序博客网 时间:2024/06/05 18:44

一、定义

      二叉搜索树,Binary Search Tree,是具有这样一种性质的二叉树:对于树中的每个结点X,它的左子树中所有项的值小于X中的项,它的右子树中所有项的值大于X中的项。

      此性质意味着只要中序遍历一下便可得到一个有序的序列。

      定义二叉搜索树的数据结构:

typedef struct TreeNode *BinTree;struct TreeNode{    int key;    BinTree left;    BinTree right;    TreeNode(int _key = 0):key(_key), left(NULL), right(NULL){}};

二、操作

     BST上的操作主要有:

     1. 查找(search)

        递归版本(尾递归)

BinTree Search(BinTree T, int key){    if(!T || key == T->key)        return T;    if(key < T->key)        return Search(T->left, key);    else        return Search(T->right, key);

        迭代版本

BinTree Search(BinTree T, int key){    while(T && key != T->key)    {        if(key < T->key)            T = T->left;        else if(key > T->key)            T = T->right;    }    return T;}


      2. 查找最大最小值

查找最大值(递归)

BinTree findMax(BinTree T){    if(!T) return NULL;    if(!T->right)        return T;    else return findMax(T->right);}

查找最小值(迭代)

BinTree findMin(BinTree T){    while(T && T->left)        T = T->left;    return T;}


      3. 插入

递归

BinTree Insert(BinTree T, int key){    if(!T){        T = new TreeNode(key);    }    else if(key < T->key)        T->left  = Insert(T->left, key);    else if(key > T->key)        T->right = Insert(T->right, key);    return T;}

迭代

BinTree Insert(BinTree T, int key){    BinTree parent = NULL;     //待插入结点的父结点    BinTree p = T;    while(p)    {        parent = p;        if(key < p->key)            p = p->left;        else            p = p->right;    }    if(!parent)                //空树        T = new TreeNode(key);    else if(key < parent->key)        parent->left = new TreeNode(key);    else        parent->right = new TreeNode(key);    return T;}

       4. 删除

删除某个结点之前是先查找,找到的待删除结点T有三种可能情况:
1. 只具有左子树,只需 T = T->left;
2. 只具有右子树,只需 T = T->right;
3. 具有左右子树,这种情况更为复杂,在T的右子树中找最小key的结点或者在T的左子树中找最大key的结点,以此值替换T的key,然后删除右子树中的最小值或者左子树中的最大值,这又是一个递归的情况。

BinTree Delete(BinTree T, int key){    if(!T) cerr << "not founded, failed deleting!" << endl;    else if(key < T->key)        T->left = Delete(T->left, key);    else if(key > T->key)        T->right = Delete(T->right, key);    else    {        BinTree Tmp;        if(T->left && T->right){            Tmp = findMin(T->right);            T->key = Tmp->key;            T->right = Delete(T->right, T->key);        }        else{            Tmp = T;            if(!T->left)                T = T->right;            else if(!T->right)                T = T->left;            delete Tmp;        }    }    return T;}

      5. 前驱和后继

 算导上也给出了关于BST中结点前驱和后继的描述,假设所有的关键字互不相同:

后继:一个结点的后继是大于其key的最小关键字的结点;

前驱:一个结点的前驱是小于其key的最大关键字的结点。

给定一个结点x,如何查找其后继呢?分两种情况:

1. 如果该结点的右子树非空,那么x的后继恰是x右子树中的最左节点;

2. 如果该结点的右子树为空且其后继存在,只要简单地从x开始沿树而上直到找到这样一个结点,这个结点是其父节点的左孩子。

(需要在TreeNode中增加一个parent指针,指示其父节点,同时Insert函数也需要稍作修改)

BinTree Successor(BinTree T, int key){    BinTree x = Search(T, key);    if(x->right)        return findMin(x->right);    BinTree y = x->parent;    while(y && x == y->right)    {        x = y;        y = y->parent;    }    return y;}


求前驱是求后继的对称过程:

BinTree Precursor(BinTree T, int key){    BinTree x = Search(T, key);    if(x->left)        return findMax(T->left);    BinTree y = x->parent;    while(y && x == y->left)    {        x = y;        y = y->parent;    }    return y;}





0 0
原创粉丝点击