二叉搜索树
一、定义和性质:
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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。