二叉排序树,也称作二叉查找树,一般定义为或者是空树,或者是满足以下条件的二叉树:
(1)若它的左子树不空,则左子树上所有记录的关键字值均小于根记录关键字的值。
(2)若它的右子树不空,则右子树上所有记录的关键字均大于根记录关键字的值。
(3) 它的左、右子树本身也是二叉排序树。
#include<stdio.h> typedef int keytype; //数据域值类型 typedef struct node { keytype data; //数据域 struct node *left,*right; //左、右链域 }Bitree; //二叉排序树结点数据类型
!-----------二叉排序树的查找
1.递归查找算法
Bitree *F = NULL; //存放双亲结点指针,插入和删除时使用 Bitree *find(Bitree *T,keytype x) { if(T==NULL) return NULL; if(T-data==x) return T; else { F = T; if(T->data>x) find(T->left,x); else find(T->right,x); } }
2.非递归查找算法
Bitree *F = NULL; //存放双亲结点指针,插入和删除时使用 Bitree *searchbst(Bitree *T,keytype key) { Bitree *C = NULL; while(T!=NULL) if(T->data==key) {C=T;break;} else if(key<T->data) {F=T;T=T->left;} else {F=T;T=T->right;} return C; }
!-------------二叉排序树的插入
向二叉树中插入一个新元素的算法思路:
(1)在插入之前,先使用查找算法在树中检查要插入的元素是否存在。
(2)搜索成功:树中已有这个元素,不再插入,可能会做删除操作。
(3)搜索失败:树中没有关键字值等于给定值的结点,将新元素接入到查找停止处。
Bitree *insertbst(Bitree *T,keytype key) { Bitree *C,*s; C = searchbst(T,key); if(C==NULL) { s = (Bitree*)malloc(sizeof(Bitree)); s->data = key; s->left = s->right = NULL; if(F==NULL) T=s; else if(key<F->data)F->left = s; else F->right = s; } return T; }
!---------二叉排序树的创建
Bitree *creatbst() { keytype key; Bitree *T = NULL; scanf("%d",&key); while(key!=-1) { T = insertbst(T,key); scanf("%d",&key); } return T; }
!-------二叉排序树的删除
(1)删除叶子结点,只需将其双亲结点中指向它的指针置空,再释放它即可。
(2)被删结点无右子树,可以用它的左孩子结点顶替它的位置,再释放它。
(3)被删结点无左子树,可以用它的右孩子结点顶替它的位置,再释放它。
(4)被删结点同时有左子树和右子树,用左子树的最右下结点替换被删结点。
int deletebst(Bitree *T,keytype key) { Bitree *p,*s,*q; p = searchbst(T,key); if(!p){printf("not exist ");return 0;} if(p->left==NULL) //左子树空,则重接其右子树 {q=p;p=p->right;} else if(p->right==NULL) //右子树为空,则重接其左子树 {q=p;p=p->left;} else //左右子树都不空 {q=p;s=p->left; while(s->right!=NULL) {q=s;s=s->>right;} //找到p的左子树的最右下结点s if(q!=p) q->right=s->left; //重接q的右子树 else q->left = s->left; //重接q的左子树 q=s;p->data = s->data; //用s结点的值替换p结点的值 } if(F==NULL) T=p; //若被删除结点为根节点,则将p改为根结点 else if(q!=s) //左子树为空或右子树为空的结点p与其双亲结点重新链接 if(key<F->data) F->left = p; else F->right=p; free(q); return 1; }