二叉搜索树

 二叉搜索树是一类特殊的二叉树,它满足中序遍历得到的结果为序列的顺序排序的特点,在对数据排序、查找等方面有着非常重要用途。

性质

    二叉搜索树满足二叉树的所有性质,同时有着自身的特性。

  1. 中序遍历的结果为序列的顺序排序
  2. 节点的左子节点(以及左子树中所有元素)值小于节点的值;节点的右子节点(以及右子树中所有元素)值大于节点的值
  3. 从树根沿着左子树链数据依次减小,链的末尾为所有数据中的最小值
  4. 从树根沿着右子树链数据依次增大,链的末尾为所有数据中的最大值
  5. 查找和插入数据的平均时间复杂度为 O(log2n),在最坏情况(当二叉树退化成一条链时)下为O(n)。其中n为树中节点的数目

 

实现(c++)

struct TreeNode{
    int data;
    TreeNode* left;
    TreeNode* right;
    TreeNode* parent;
    TreeNode(int d) :
        data(d), left(NULL), right(NULL), parent(NULL){};
};

//返回树中的最小元素节点
TreeNode* MinNode(TreeNode* root){
    TreeNode* node = root;
    while (node->left){
        node = node->left;
    }
    return node;
}
//返回树中最大元素节点
TreeNode* MaxNode(TreeNode* root){
    TreeNode* node = root;
    while (node->right){
        node = node->right;
    }
    return node;
}

//找出树中节点元素值等于给定值的节点
TreeNode* FindElement(TreeNode* root, int k){
    TreeNode* node = root;
    while (node){
        if (node->data == k){
            return node;
        }
        else if (node->data < k){
            node = node->left;
        }
        else{
            node = node->right;
        }
    }
    return node;
}

//向树中插入新元素
TreeNode* InsertElement(TreeNode* root, int k){
    TreeNode* node = root, *new_node;
    while (node){
        if (k > node->data){
            if (node->right == NULL){
                new_node = new TreeNode(k);
                node->right = new_node;
                new_node->parent = node;
                break;
            }
            node = node->right;
        }
        else{
            if (node->left == NULL){
                new_node = new TreeNode(k);
                node->left = new_node;
                new_node->parent = node;
                break;
            }
            node = node->left;
        }
    }
    return new_node;
}

//删除树中的元素
void DeleteNode(TreeNode* node){
    TreeNode* p = node->parent;
    if (p == NULL){
        return;
    }
    if (!node->left && !node->right){    //没有子节点
        if (p->left == node){
            p->left = NULL;
        }
        else{
            p->right = NULL;
        }
        delete node;
    }
    else if (node->left && !node->right){ //只有左子节点
        if (p->left == node){
            p->left = node->left;
        }
        else{
            p->right = node->left;
        }
        node->left->parent = p;
        delete node;
    }
    else if (!node->left && node->right){ //只有右子节点
        if (p->left == node){
            p->left = node->right;
        }
        else{
            p->right = node->right;
        }
        node->right->parent = p;
        delete node;
    }
    else{    //存在左右子节点: 先找到该节点的后继节点; 然后将该节点的内容替换为其后继节点的内容,再将后继节点删除
        TreeNode* suc = Successor(node);
        node->data = suc->data;
        DeleteNode(suc);
    }
}

//返回节点node的前驱节点(在中序遍历二叉搜索树时)
TreeNode* Predecessor(TreeNode* node){
    TreeNode* pre = NULL;
    if (node->left){        //如果该节点存在左子树,则返回其左子树中的最大节点
        return MaxNode(node->left);
    }
    else{
        pre = node->parent;
        while (pre){//如果不存在左子树,则沿着父节点向上寻找,直到找到最低的一个祖先节点,使得node节点在该祖先节点的右子树上
            if (pre->right == node){
                return pre;
            }
            node = pre;
            pre = node->parent;
        }
    }
    return pre;
}

//返回节点的后继节点(在中序遍历二叉搜索树时)
TreeNode* Successor(TreeNode* node){
    TreeNode* succ = NULL;
    if (node->right){        //如果节点存在右子树,则返回右子树中的最小节点
        return MinNode(node->right);
    }
    else{
        succ = node->parent;
        while (succ){//如果节点不存在右子树,则沿着父节点向上查找,直到某个祖先节点使得该节点位于该祖先节点的左子树上
            if (succ->left == node){
                return succ;
            }
            node = succ;
            succ = node->parent;
        }
    }
    return succ;
}

 

posted @ 2015-08-05 11:01  农民伯伯-Coding  阅读(203)  评论(0编辑  收藏  举报