花了3个多小时把二叉搜索树给好好学了下并把它写了出来,,具体怎么操作看下面代码注释,最麻烦的还是删除操作
代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct BST{
int x; //关键字
struct BST *p,*left,*right; //双亲节点,左孩子,右孩子
BST(){}
BST(int k){
x = k;
p = NULL,left = NULL,right=NULL;
}
}BSTnode;
//************************查找************************
BSTnode* tree_search(BSTnode *&T,int k){ //递归查找
if(T == NULL || T->x == k) //等于NULL或找到K返回
return T;
if(k < T->x) //比当前节点小就找左子树
return tree_search(T->left,k);
else //比当前节点大就找右子树
return tree_search(T->right,k);
}
BSTnode* interative_tree_search(BSTnode *&T,int k){ //迭代查找
BSTnode *t = T;
while(t != NULL && t->x != k){
if(k < t->x)
t = t->left;
else
t = t->right;
}
return t;
}
//************************查找************************
//************************最大关键字查询,最小关键字查询,前驱和后继查询************************
BSTnode* tree_minmum(BSTnode *&T){ //最小关键字查询
BSTnode *t = T;
while(t->left != NULL){
t = t->left;
}
return t;
}
BSTnode* tree_maxmum(BSTnode *&T){ //最大关键字查询
BSTnode *t = T;
while(t->right != NULL){
t = t->right;
}
return t;
}
BSTnode* tree_successor(BSTnode *&T){ //后继查询,后继就是大于T.x的最小关键字节点
BSTnode *t = T,*y = NULL;
if(t->right != NULL) //如果右子树不为空直接求右子树的最小节点
return tree_minmum(t->right);
y = t->p;
while(y != NULL && y->right == t){
t = y;
y = t->p;
}
return y;
}
BSTnode* tree_predecessor(BSTnode *&T){ //前驱查询,前驱就是小于T.x的最大关键字节点
BSTnode *t = T,*y = NULL;
if(t->left != NULL) //如果左子树不为空直接求左子树的最大节点
return tree_predecessor(t->left);
y = t->p;
while(y != NULL && y->left == t){ //这里就是没有左子树的情况,往上找,看看上面还有没有小于t.x的节点
t = y;
y = t->p;
}
return y;
}
//************************最大关键字查询,最小关键字查询,前驱和后继查询************************
//************************插入************************
void tree_insert(BSTnode *&T,int k){
BSTnode *t = T,*y = NULL;
BSTnode *z = new BSTnode(k);
while(t != NULL){
y = t;
if(z->x < t->x)
t = t->left;
else
t = t->right;
}
z->p = y;
if(y == NULL) //如果y为空
T = z;
else if(z->x < y->x) //如果z的关键字小于y的关键字,那么放y的左边,否则就是右边
y->left = z;
else
y->right = z;
}
//************************插入************************
//************************删除************************
void transplant(BSTnode *&T,BSTnode *&u,BSTnode *&v){//移动子树
if(u->p == NULL) //如果u是根节点,那么直接去掉
T = v;
else if(u == u->p->left) //如果u是u->p的左孩子
u->p->left = v;
else //如果u是u->p的右孩子
u->p->right = v;
if(v!=NULL){ //更新v的双亲
v->p = u->p;
}
}
void tree_delete(BSTnode *&T,BSTnode *&z){
if(z->left == NULL) //如果z的左孩子为空,那么直接把右子树移上来
transplant(T,z,z->right);
else if(z->right == NULL) //如果z的右孩子为空,那么直接把左孩子移上来
transplant(T,z,z->left);
else{ //如果左右孩子都在
BSTnode *y = tree_minmum(z->right); //找到右子树最小的节点
if(y->p != z){ //如果z不是y的双亲节点,那么说明y有不是z的双亲节点
transplant(T,y,y->right); //把y的左子树向上移,把y取出来
y->right = z->right; //把z连好的右子树放到y的右子树那边
y->right->p = y; //更新y的右子树的双亲
}
transplant(T,z,y); //因为y是z的右子树最小节点,那么肯定没有左子树,直接上移,在把z的左子树放到y的左边,再更新y的左子树的双亲
y->left = z->left;
y->left->p = y;
}
}
//************************删除************************
void inorder_input(BSTnode *&T){ //中序遍历输出
if(T!=NULL){
inorder_input(T->left);
printf("%d ",T->x);
inorder_input(T->right);
}
}
int main(){
int n;
// scanf("输入节点数:%d",&n);
// printf("\n输入关键字:");
int x;
BSTnode *T = NULL;
int a[10] = {0,12,5,18,2,9,15,19,13,17};
for(int i = 1;i<=9;i++){
// int x;
// scanf("%d",&x);
tree_insert(T,a[i]); //插入到树中
}
printf("before sequence is altered: \n");
inorder_input(T);
putchar('\n');
printf("after digit 14 is inserted,sequence being print by the inorder: \n");
tree_insert(T,14);
inorder_input(T);
putchar('\n');
printf("after digit 5 is deleted,sequence being print by the inorder: \n");
BSTnode *z = tree_search(T,5);
if(z != NULL)
tree_delete(T,z);
inorder_input(T);
putchar('\n');
system("pause");
return 0;
}