您的位置:首页 > 其它

二叉查找树(binary search tree (BST))--算法导论示例

2008-01-27 17:14 731 查看
二叉查找树(binary search tree (BST))--算法导论示例

二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树:

1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 它的左、右子树也分别为二叉排序树。

二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)).

二叉排序树的查找算法

在二叉排序树b中查找x的过程为:

若b是空树,则搜索失败,否则:

若x等于b的根结点的数据域之值,则查找成功;否则:

若x小于b的根结点的数据域之值,则搜索左子树;否则:

查找右子树。

在二叉排序树插入结点的算法

向一个二叉排序树b中插入一个结点s的算法,过程为:

若b是空树,则将s所指结点作为根结点插入,否则:

若s->data等于b的根结点的数据域之值,则返回,否则:

若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中,否则:

把s所指结点插入到右子树中。

在二叉排序树删除结点的算法

在二叉排序树删去一个结点,分三种情况讨论:

若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。

右*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树即可,作此修改也不破坏二叉排序树的特性。

若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以有两种做法:其一是令*p的左子树为*f的左子树,*s为*f左子树的最右下的结点,而*p的右子树为*s的右子树;其二是令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)。

二叉排序树性能分析

每个结点的Ci为该结点的层次数。最坏情况下,当先后插入的关键字有序时,构成的二叉排序树蜕变为单支树,树的深度为n,其平均查找长度为(n+1)/2(和顺序查找相同),最好的情况是二叉排序树的形态和折半查找的判定树相同,其平均查找长度和log2n成正比(O(log2n))。


#include "stdio.h"


#include "stdlib.h"




struct Node




...{


int key;//结点值


struct Node *parent;//父结点


struct Node *left;//左结点


struct Node *right;//右结点


};




//打印二叉树


void PrintTree(struct Node *Root)




...{


struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));


pointer=Root;


if(pointer!=NULL)




...{


PrintTree(pointer->left);


printf("%d ",pointer->key);


PrintTree(pointer->right);


}


}




//删除树,递归释放树的结点


void DeleteTree(struct Node *Root)




...{


struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));


pointer=Root;




if(pointer!=NULL)




...{


DeleteTree(pointer->left);


free(pointer);


DeleteTree(pointer->right);


}


}




//最小值


struct Node *Minimum(struct Node *Root)




...{


struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));


pointer=Root;




while(pointer->left!=NULL)


pointer=pointer->left;




return pointer;


}




//最大值


struct Node *Maximum(struct Node *Root)




...{


struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));


pointer=Root;




while(pointer->right!=NULL)


pointer=pointer->right;




return pointer;


}




//查找


struct Node *Search(struct Node *Root,int value)




...{


struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));


pointer=Root;




while(pointer!=NULL&&pointer->key!=value)




...{


//如果查找值比结点值小,查找它的左子树


if(value<pointer->key)


pointer=pointer->left;


else


pointer=pointer->right;//如果查找值比结点值大,查找它的右子树


}




return pointer;


}




//后继


struct Node *Successor(struct Node *pointer)




...{


if(pointer->right!=NULL)


return Minimum(pointer->right);




struct Node *y=(struct Node*)malloc(sizeof(struct Node));


y=pointer->parent;


while(y!=NULL&&y->right==pointer)




...{


pointer=y;


y=pointer->parent;


}




return y;


}




//前驱


struct Node *Predecessor(struct Node *pointer)




...{


if(pointer->left!=NULL)


return Maximum(pointer->left);




struct Node *y=(struct Node*)malloc(sizeof(struct Node));


y=pointer->parent;


while(y!=NULL&&y->left==pointer)




...{


pointer=y;


y=pointer->parent;


}




return y;


}




//插入新结点


struct Node *Insert(struct Node *Root,struct Node *newNode)




...{


struct Node *back=(struct Node*)malloc(sizeof(struct Node));


struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));


back=NULL;


pointer=Root;




//找到要插入的位置


while(pointer!=NULL)




...{


back=pointer;


if(newNode->key<pointer->key)


pointer=pointer->left;


else


pointer=pointer->right;


}




//新结点的Parent指针先指向父结点


newNode->parent=back;




if(back==NULL)


Root=newNode;//树为空,新结点成为树根


else




...{


if(newNode->key<back->key)


back->left=newNode;


else


back->right=newNode;


}




return Root;


}




//删除结点


struct Node *Delete(struct Node *Root,struct Node *pointer)




...{


struct Node *y=(struct Node*)malloc(sizeof(struct Node));


y->parent=NULL;


y->left=NULL;


y->right=NULL;


//找到实际要删除的结点


if(pointer->left==NULL||pointer->right==NULL)


y=pointer;


else


y=Successor(pointer);




struct Node *x=(struct Node*)malloc(sizeof(struct Node));


x->parent=NULL;


x->left=NULL;


x->right=NULL;


//要删除结点的子结点


if(y->left!=NULL)


x=y->left;


else


x=y->right;




if(x!=NULL)


x->parent=y->parent;




if(y->parent==NULL)


Root=x;//删除的是根结点


else




...{


if(y==y->parent->left)


y->parent->left=x;


else


y->parent->right=x;


}




if(y!=pointer)


pointer->key=y->key;




if(y!=NULL)




...{


free(y);


printf("Delete success! ");


}


else


printf("Delete failure! ");




return Root;


}




int main()




...{


struct Node *Root=NULL;


int value;




int flag=1;


while(flag)




...{


printf("1:Insert ");


printf("2:Delete ");


printf("3:Search ");


printf("4:Minimum ");


printf("5:Maximum ");


printf("6:Successor ");


printf("7:Predecessor ");


printf("0:Exit ");


printf("Please input your choice:");


scanf("%d",&flag);




switch(flag)




...{


case 0:


return 0;


case 1:




...{


printf("Please input the value you want to input:");


scanf("%d",&value);


struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));


newNode->key=value;


newNode->parent=NULL;


newNode->left=NULL;


newNode->right=NULL;


Root=Insert(Root,newNode);


break;


}


case 2:




...{


printf("Please input the value you want to delete:");


scanf("%d",&value);


struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));


newNode=Search(Root,value);


if(newNode!=NULL)


Root=Delete(Root,newNode);


else


printf("%d does'n exist in this tree! ",value);


break;


}


case 3:




...{


printf("Please input the value you want to input:");


scanf("%d",&value);


struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));


newNode=Search(Root,value);


if(newNode!=NULL)


printf("%d exist in this tree! ",newNode->key);


else


printf("%d does'n exist in this tree! ",value);


break;


}


case 4:




...{


if(Root!=NULL)




...{


struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));


newNode=Minimum(Root);


printf("The minimum value of this tree is %d! ",newNode->key);


}


else


printf("This tree is empty! ");


break;


}


case 5:




...{


if(Root!=NULL)




...{


struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));


newNode=Maximum(Root);


printf("The Maximum value of this tree is %d! ",newNode->key);


}


else


printf("This tree is empty! ");


break;


}


case 6:




...{


printf("Please input the value:");


scanf("%d",&value);


struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));


newNode=Search(Root,value);


if(newNode!=NULL)




...{


newNode=Successor(newNode);


if(newNode!=NULL)


printf("%d's successor is %d! ",value,newNode->key);


else


printf("%d has't successor int this tree! ",value);


}


else


printf("%d does'n exist in this tree! ",value);


break;


}


case 7:




...{


printf("Please input the value:");


scanf("%d",&value);


struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));


newNode=Search(Root,value);


if(newNode!=NULL)




...{


newNode=Predecessor(newNode);


if(newNode!=NULL)


printf("%d's Predecessor is %d! ",value,newNode->key);


else


printf("%d has't predecessor int this tree! ",value);


}


else


printf("%d does'n exist in this tree! ",value);


break;


}


default:


break;


}




PrintTree(Root);


}




DeleteTree(Root);


return 0;


}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐