二叉搜索树

一、定义和性质:

1、定义

二叉查找树(Binary Search Tree),又被称为二叉搜索树。

它是特殊的二叉树:

对于二叉树,假设x为二叉树中的任意一个结点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y] <= key[x];如果y是x的右子树的一个结点,则key[y] >= key[x]。那么,这棵树就是二叉查找树。

2、性质

二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:

1、每个结点都有一个作为搜索依据的关键码(key),所有结点的关键码互不相同。

2、左子树(如果非空)上所有结点的关键码都小于根结点的关键码。

3、右子树(如果非空)上所有结点的关键码都大于根结点的关键码。

4、左子树和右子树也是二叉搜索树。

5、结点左子树上所有关键码小于结点关键码;

6、右子树上所有关键码大于结点关键码;

7、若从根结点到某个叶结点有一条路径,路径左边的结点的关键码不一定小于路径上的结点的关键码。

8、如果对一棵二叉搜索树进行中序遍历,可以按从小到大的顺序,将各结点关键码排列起来,所以也称二叉搜索树为二叉排序树。

二、二叉搜索树的实现

#include <iostream>

using namespace std;

struct BST_Node
{
    BST_Node *left;
    BST_Node *right; 
    BST_Node *parent;
    int key;
};


//中序遍历,按顺序输出
void InOrder_Tree_Walk(BST_Node *x)
{
    if (x != NULL)
    {
        InOrder_Tree_Walk(x->left);
        cout << x->key << " ";
        InOrder_Tree_Walk(x->right);
    }
}

//递归查找
BST_Node *D_Tree_Search(BST_Node *x, int k)
{
    if ((x == NULL) || (k == x->key))
        return x;
    if (k < x->key)
        return D_Tree_Search(x->left, k);
    else
        return D_Tree_Search(x->right, k);
}

//迭代查找
BST_Node *Iterative_Tree_Search(BST_Node *x, int k)
{
    while ((x != NULL) && (k != x->key))
    {
        if (k < x->key)
            x = x->left;
        else
            x = x->right;
    }

    return x;
}

//迭代法求最小值
BST_Node *Iterative_Tree_Minimum(BST_Node *x)
{
    while (x->left != NULL)
        x = x->left;
    return x;
}


//递归法求最小值
BST_Node *D_Tree_Minimum(BST_Node *x)
{
    if (x->left == NULL)
        return x;
    else
        return D_Tree_Minimum(x->left);

}

//迭代法求最大值
BST_Node *Iterative_Tree_Maximum(BST_Node *x)
{
    while (x->right != NULL)
        x = x->right;
    return x;
}

//递归法求最大值
BST_Node *D_Tree_Maximum(BST_Node *x)
{
    if (x->right == NULL)
        return x;
    else
        return D_Tree_Maximum(x->right);

}

BST_Node *Tree_Successor(BST_Node *Root, int k)
{
    BST_Node *x = D_Tree_Search(Root, k);

    if (x->right != NULL)
        return Iterative_Tree_Minimum(x->right);
    else
    {
        BST_Node *y = x->parent;
        while ((y != NULL) && (x == y->right))//y==NULL  返回根节点的双亲,表示无后继节点
        {                                     //x != y->right 表示前面一串节点是当前y的左孩子  
            x = y;                             //此时的y是后继  
            y = y->parent;
        }

        return y;
    }
}

BST_Node *Tree_Predecessor(BST_Node *Root , int k)
{
    BST_Node *x = D_Tree_Search(Root, k);

    if (x->left != NULL)//若左孩子非空,左孩子的最大值就是前驱
        return Iterative_Tree_Maximum(x->left);
    else//若左孩子为空
    {
        BST_Node *y = x->parent;  //依次向上找到整体作为左子树的双亲节点,即为前驱
        while ((y != NULL) && (x == y->left))
        {
            x = y;
            y = y->parent;
        }

        return y;
    }
}

//迭代法插入
BST_Node *Iterative_Tree_Insert(BST_Node *Root, int k)
{
    BST_Node *z = new BST_Node;
    z->key = k;
    z->left = z->right = z->parent = NULL;

    BST_Node *y = NULL;
    BST_Node *x = Root;

    while (x != NULL)//x,y两个指针向下移动,直到x为NULL,这个NULL占据位就是z要放置的地方
    {
        y = x;//当前x节点存到y,遍历指针y作为x的双亲
        if (z->key < x->key)
            x = x->left;
        else
            x = x->right;
    }

    z->parent = y;//将y作为z的双亲

    if (y == NULL)//此时二叉树为空
        Root = z;
    else if (z->key < y->key)//如果z关键字小于z的双亲y的关键字,则z作为y的左孩子
        y->left = z;          //否则作为右孩子
    else
        y->right = z;


    return Root;
}

//递归法插入
BST_Node *D_Tree_Insert(BST_Node *Root, int k)
{
    if (!Root)
    {//若原树为空,生成并返回一个节点的二叉搜索树 
        Root->key = k;
        Root->left = NULL;
        Root->right = NULL;
    }   
    else //开始找要插入元素的位置 
    {
        if (k <= Root->key)//递归插入左子树  
            Root->left = D_Tree_Insert(Root->left, k);

        else              //递归插入右子树  
            Root->right = D_Tree_Insert(Root->right, k);
    }

    return Root;

}

//有数组A[]建立二叉搜索树
BST_Node *Establish_Tree(int *A, int Length)
{
    BST_Node *Root = NULL;

    for (int i = 0; i < Length; ++i)
        Root = Iterative_Tree_Insert(Root, A[i]);

    return Root;

}

//一棵子树替代另一棵子树
void Transplant(BST_Node *Root, BST_Node *u, BST_Node *v)
{


    if (u->parent == NULL)//u为根节点
        Root = v;
    else if (u = u->parent->left)//u是左子树
        u->parent->left = v;
    else
        u->parent->right = v;  //u是右子树

    if (v != NULL)     //更新双亲节点,左右子树节点待更新
        v->parent = u->parent;
}

//删除节点
BST_Node *Tree_Delete(BST_Node *Root, int k)
{
    BST_Node *z  = D_Tree_Search(Root, k);

    if (z->left == NULL)
        Transplant(Root, z, z->right);
    else if (z->right == NULL)
        Transplant(Root, z, z->left);
    else
    {
        //寻找z节点后继节点
        BST_Node *y = Iterative_Tree_Minimum(z->right);

        if (y->parent != z)//右孩子不是z的后继
        {
            Transplant(Root, y, y->right);//将后继的右孩子替代后继,并更新y节点的右孩子
            y->right = z->right;
            y->right->parent = y;
        }

        Transplant(Root, z, y);//用y替代z,并更新y的左孩子
        y->left = z->left;
        y->left->parent = y;

    }


    return Root;
}


int main()
{
    int A[] = { 3, 10, 2, 5, 9, 7, 4, 1, 6, 8 };
    int Length = sizeof(A) / sizeof(A[0]);

    BST_Node *Root;
    Root = Establish_Tree(A, Length);

    cout << "中序遍历输出所有节点值:";
    InOrder_Tree_Walk(Root);
    cout << endl;

    cout << "4的后继是:" << Tree_Successor(Root, 4)->key << endl;
    cout << "7的前驱是:" << Tree_Predecessor(Root, 7)->key << endl;

    cout << "迭代法的最小值是:" << Iterative_Tree_Minimum(Root)->key << endl;
    cout << "递归法的最小值是:" << D_Tree_Minimum(Root)->key << endl;

    cout << "迭代法的最大值是:" << Iterative_Tree_Maximum(Root)->key << endl;
    cout << "递归法的最大值是:" << D_Tree_Maximum(Root)->key << endl;

    cout << "迭代法插入4:";
    Root = Iterative_Tree_Insert(Root, 4);
    cout << "中序遍历输出所有节点值:";
    InOrder_Tree_Walk(Root);
    cout << endl;

    cout << "递归法插入8:";
    Root = D_Tree_Insert(Root, 8);
    cout << "中序遍历输出所有节点值:";
    InOrder_Tree_Walk(Root);
    cout << endl;

    cout << "删除5:";
    Root = Tree_Delete(Root, 5);
    cout << "中序遍历输出所有节点值:";
    InOrder_Tree_Walk(Root);
    cout << endl;

    system("pause");
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-09-22 21:01  taxue505  阅读(207)  评论(0编辑  收藏  举报