二叉搜索树的实现:
备注:算法导论中文版第168页中删除节点时候,y=TREE_MINIMUM(z.right)是错误的,应该寻找后继结点,为y=TREE_SUCCESSOR(z.right).
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
typedef struct TREE{
int data;
struct TREE *lchild;
struct TREE *rchild;
struct TREE *parent;
} Tree;
//中序遍历
void inorderTreeWalk( Tree *tree );
//在二叉搜索树中进行查找
Tree *treeSearch( Tree *tree, int value );
//返回二叉搜索树的最小值
Tree *treeMinimum( Tree *tree );
//返回二叉搜索树的最大值
Tree *treeMaximum( Tree *tree );
//返回指定节点的后继结点(结点x的后继是大于x.key的最小关键字的结点)
Tree *treeSuccessor( Tree *x );
//返回指定节点的前驱结点(结点x的前驱是小于x.key的最大关键字的结点)
Tree *treePrev( Tree *x );
//插入结点
void treeInsert( Tree *tree, int value );
//删除结点
int treeDelete( Tree *tree, int value );
//将树v替换为树u
void transplant( Tree *tree, Tree *u, Tree *v );
int main( void )
{
int i = 0;
Tree *tree = ( Tree * )malloc( sizeof( Tree ) );
tree->data = INT_MIN;
tree->lchild = tree->rchild = tree->parent = NULL;
treeInsert( tree, 6 );
treeInsert( tree, 3 );
treeInsert( tree, 8 );
treeInsert( tree, 1 );
treeInsert( tree, 5 );
treeInsert( tree, 7 );
treeInsert( tree, 9 );
treeInsert( tree, 0 );
treeInsert( tree, 2 );
treeInsert( tree, 4 );
printf("the tree is:\n");
//设计为root结点的右孩子指向这棵树
inorderTreeWalk( tree->rchild );
if ( treeSearch( tree->rchild, 12 ) ){
printf("\n12 is in the tree.\n");
}
else{
printf("\n12 is not in the tree\n");
}
printf("the tree minimum number is: %d\n", treeMinimum( tree->rchild )->data );
printf("the tree maximum number is: %d\n", treeMaximum( tree->rchild )->data );
for ( i = 5; i < 9; i++ ){
treeDelete( tree, i );
}
printf("after delete element 5~8, the tree is:\n");
inorderTreeWalk( tree->rchild );
return 0;
}
void inorderTreeWalk( Tree *tree )
{
if ( NULL != tree ){
inorderTreeWalk( tree->lchild );
printf("%d ", tree->data );
inorderTreeWalk( tree->rchild );
}
}
Tree *treeSearch( Tree *tree, int value )
{
if ( NULL == tree || tree->data == value ){
return tree;
}
if ( value < tree->data ){
return treeSearch( tree->lchild, value );
}
else{
return treeSearch( tree->rchild, value );
}
}
Tree *treeMinimum( Tree *tree )
{
while ( NULL != tree->lchild ){
tree = tree->lchild;
}
return tree;
}
Tree *treeMaximum( Tree *tree )
{
while ( NULL != tree->rchild ){
tree = tree->rchild;
}
return tree;
}
Tree *treeSuccessor( Tree *x )
{
Tree *y = ( Tree * )malloc( sizeof( Tree ) );
if ( NULL != x->rchild ){
return treeMinimum( x->rchild );
}
y = x->parent;
while ( NULL != y && x == y->rchild ){
x = y;
y = y->parent;
}
return y;
}
Tree *treePrev( Tree *x )
{
Tree *y = ( Tree * )malloc( sizeof( Tree ) );
if ( NULL != x->lchild ){
return treeMaximum( x->lchild );
}
y = x->parent;
while ( NULL != y && x == y->lchild ){
x = y;
y = y->parent;
}
return y;
}
void treeInsert( Tree *tree, int value )
{
Tree *newNode = ( Tree * )malloc( sizeof( Tree ) );
newNode->data = value;
newNode->lchild = newNode->rchild = newNode->parent = NULL;
if ( NULL == tree->rchild ){
tree->lchild = tree->rchild = newNode;
}
else{
Tree *prevNode = ( Tree * )malloc( sizeof( Tree ) );
tree = tree->rchild;
prevNode = tree;
while ( NULL != tree ){
prevNode = tree;
if ( value < tree->data ){
tree = tree->lchild;
}
else{
tree = tree->rchild;
}
}
newNode->parent = prevNode;
if ( newNode->data < prevNode->data ){
prevNode->lchild = newNode;
}
else{
prevNode->rchild = newNode;
}
}
}
int treeDelete( Tree *tree, int value )
{
Tree *deleteNode = ( Tree * )malloc( sizeof( Tree ) );
deleteNode = treeSearch( tree->rchild, value );
if ( NULL == deleteNode ){
return 0;
}
if ( NULL == deleteNode->lchild ){
transplant( tree, deleteNode, deleteNode->rchild );
}
else if ( NULL == deleteNode->rchild ){
transplant( tree, deleteNode, deleteNode->lchild );
}
else{
Tree *y = ( Tree * )malloc( sizeof( Tree ) );
y = treeSuccessor( deleteNode );
if ( deleteNode != y->parent ){
transplant( tree, y, y->rchild );
y->rchild = deleteNode->rchild;
y->rchild->parent = y;
}
transplant( tree, deleteNode, y );
y->lchild = deleteNode->lchild;
y->lchild->parent = y;
}
return 1;
}
void transplant( Tree *tree, Tree *u, Tree *v )
{
if ( NULL == u->parent ){
tree->rchild = tree->lchild = v;
}
else if ( u == u->parent->lchild ){
u->parent->lchild = v;
}
else{
u->parent->rchild = v;
}
if ( NULL != v ){
v->parent = u->parent;
}
}
用随机产生的数来构建二叉搜索树,main函数如下:
int main( void )
{
int i = 0;
Tree *tree = ( Tree * )malloc( sizeof( Tree ) );
tree->data = INT_MIN;
tree->lchild = tree->rchild = tree->parent = NULL;
srand( ( unsigned int )time( NULL ) );
for ( i = 0; i < 10; i++ ){
treeInsert( tree, rand() % 20 );
}
printf("the tree is:\n");
//设计为root结点的右孩子指向这棵树
inorderTreeWalk( tree->rchild );
if ( treeSearch( tree->rchild, 12 ) ){
printf("\n12 is in the tree.\n");
}
else{
printf("\n12 is not in the tree\n");
}
printf("the tree minimum number is: %d\n", treeMinimum( tree->rchild )->data );
printf("the tree maximum number is: %d\n", treeMaximum( tree->rchild )->data );
for ( i = 5; i < 9; i++ ){
treeDelete( tree, i );
}
printf("after delete element 5~8, the tree is:\n");
inorderTreeWalk( tree->rchild );
return 0;
}
为什么6没被删除呢?实际上有两个6,删除了其中的一个.一般的二叉搜索树是不允许重复的.如果重复,则删除节点的操作+插入的操作都得重新修改.