您的位置:首页 > 其它

【二叉树】二叉搜索树创建、插入、删除、查找等操作

2014-06-23 21:50 357 查看
二叉搜索树性质如下:

//二叉搜索树篇
#include <stdio.h>
#include <stdlib.h>

struct search_tree_typedef;
struct search_tree_typedef{
struct search_tree_typedef *p;
struct search_tree_typedef *lc;
struct search_tree_typedef *rc;
int key;
};
typedef struct search_tree_typedef stree_node;
//向二叉搜索树插入一个元素
int insert_search_tree(stree_node **T, int key){
stree_node *x, *y, *new_node;

if((new_node = (stree_node*)malloc(sizeof(stree_node)))==NULL)
return -1;
new_node->lc = NULL;
new_node->rc = NULL;
new_node->key = key;
x=*T;
if(x==NULL){
new_node->p = NULL;
*T = new_node;

return 0;
}
while(x!=NULL){
y = x;
if(key>x->key){
x = x->rc;
}
else{
x = x->lc;
}
}
new_node->p = y;
if(key>y->key)
y->rc = new_node;
else
y->lc = new_node;

return 0;
}

//创建二叉搜索树
int create_search_tree(stree_node **T){
int key;

while(1){
scanf("%d", &key);
if(key==0)
return 0;
if(insert_search_tree(T, key)==-1)
return -1;
}
}
//查找关键字为key的节点
stree_node* find_node(stree_node *T, int key){
stree_node *x;
x = T;
while(x!=NULL){
if(x->key==key)
break;
else if(key<x->key){
x=x->lc;
}
else{
x=x->rc;
}
}
return x;
}
//查找最大关键字的节点
stree_node* find_maxkey(stree_node *T){
stree_node *x, *y;

x = T;
if(T==NULL)
return NULL;
while(x!=NULL){
y = x;
x = x->rc;
}
return y;
}

//查找最小关键字的节点
stree_node* find_minkey(stree_node *T){
stree_node *x, *y;

x = T;
if(T==NULL)
return NULL;
while(x!=NULL){
y = x;
x = x->lc;
}
return  y;
}
//查找指定关键字的节点的前驱节点
stree_node* find_precursor(stree_node *T, int key){
stree_node *x, *y;

x = find_node(T, key);
if(x==NULL)
return NULL;
else{
if(x->lc==NULL){
if(x->p!=NULL){
if(x->p->rc == x){
return x->p;
}
else
return NULL;
}
}
else{
return find_maxkey(x->lc);
}
}
}

//查找指定节点的前驱结点
stree_node* find_precursor2(stree_node *x){
if(x==NULL)
return NULL;
else{
if(x->lc==NULL){
if(x->p!=NULL){
if(x->p->rc == x){
return x->p;
}
else
return NULL;
}
}
else{
return find_maxkey(x->lc);
}
}
}

//查找指定关键字key的节点的后驱节点
stree_node* find_successor(stree_node *T, int key){
stree_node *x, *y;

x = find_node(T, key);
if(x==NULL)
return NULL;
else{
if(x->rc==NULL){
if(x->p!=NULL){
if(x->p->lc == x){
return x->p;
}
else
return NULL;
}
}
else{
return find_minkey(x->rc);
}
}
}

//查找指定节点的后驱节点
stree_node* find_successor2(stree_node *x){
if(x==NULL)
return NULL;
else{
if(x->rc==NULL){
if(x->p!=NULL){
if(x->p->lc == x){
return x->p;
}
else
return NULL;
}
}
else{
return find_minkey(x->rc);
}
}
}

//删除指定关键字key的节点
int delete_stree_node(stree_node **T, int del_key){
stree_node *x, *temp;

x = find_node(*T, del_key);
if(x==NULL)
return -1;
else{
//1.如果删除结点左右子树都为空,则直接释放该结点
//2.如果删除结点左右子树其一不为空,则找出删除结点后继结点,将该后继结点代替删除结点(后继结点父节点为删除结点父节点,后继结点左子树为删除结点左子树,后继结点右子树为删除结点右子树),释放后继结点
//3.如果删除结点左右子树都不为空,则将该后继结点代替删除结点,相应修改后继结点父结点的左子树
if(x->lc==NULL&&x->rc==NULL){
if(x->p==NULL)
*T = NULL;
}
else if(x->lc&&x->rc){
//先在x的右子树找出后继结点
temp = find_successor2(x);

if(x->p==NULL){
*T = temp;
if(temp->p == x){  //x->rc->lc必为空
temp->lc = x->lc;
}
else{
temp->p->lc = temp->rc;
temp->lc = x->lc;
temp->rc = x->rc;
}
}
else{
if(x->p->lc == x)
x->p->lc = temp;
else
x->p->rc = temp;
if(temp->p == x){  //x->rc->lc必为空
temp->lc = x->lc;
}
else{
temp->p->lc = temp->rc;
temp->lc = x->lc;
temp->rc = x->rc;
}
}
}
else{
if(x->lc){
if(x->p==NULL)
*T = x->lc;
else{
if(x->p->lc == x)
x->p->lc = x->lc;
else
x->p->rc = x->lc;
}
}
else{
if(x->p==NULL)
*T = x->rc;
else{
//最简单方法就是另x->p的左子树或右子树指向x的右子树
if(x->p->lc == x)
x->p->lc = x->rc;
else
x->p->rc = x->rc;
}
}
}
free(x);
}
}

//中序遍历二叉树
void in_visit_tree(stree_node *tree){
if(tree==NULL)
return;
if(tree->lc!=NULL){
in_visit_tree(tree->lc);
}
printf("%d ", tree->key);
if(tree->rc!=NULL){
in_visit_tree(tree->rc);
}
}

//测试数据:建树序列13 5 2 9 6 18 15 17 19,中序序列为2 5 6 9 13 15 17 18 19
int main(void){
stree_node *thead=NULL;
stree_node *maxkey, *minkey, *precursor, *successor;

create_search_tree(&thead);          //测试成功
in_visit_tree(thead); printf("\n");  //测试成功
maxkey = find_maxkey(thead);         //测试成功
minkey = find_minkey(thead);         //测试成功
printf("min=%d\n", (maxkey==NULL)?-1:maxkey->key);
printf("max=%d\n", (minkey==NULL)?-1:minkey->key);
precursor = find_precursor(thead, minkey->key);
successor = find_successor(thead, 13);
printf("precursor=%d\n", (precursor==NULL)?-1:precursor->key);        //测试成功
printf("successor=%d\n", (successor==NULL)?-1:successor->key);        //测试成功

delete_stree_node(&thead, 5);        //测试成功
in_visit_tree(thead); printf("\n");

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: