#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int SearchBST(BiTree T,ElemType key,BiTree f,BiTree *p)
{
if(!T)
{
*p = f;
return 0;
}
else
{
if(key == T->data)
{
*p = T;
return 1;
}
else
{
if(key < T->data)
{
return SearchBST(T->lchild,key,T,p);
}
else
{
return SearchBST(T->rchild,key,T,p);
}
}
}
}
int InsertBST(BiTree *T,ElemType key)
{
BiTree p,s;
if(!SearchBST(*T,key,NULL,&p))
{
s = (BiTree)malloc(sizeof(BiTNode));
s->data = key;
s->lchild = s->rchild =NULL;
if(!p)
{
*T = s;
}
else
{
if(key < p->data)
{
p->lchild = s;
}
else
{
p->rchild = s;
}
}
return 1;
}
else
{
return 0;
}
}
int Delete(BiTree *p)
{
BiTree q,s;
if((*p)->rchild == NULL) //右子树为空
{
q = *p;
*p = (*p)->lchild;
free(q);
}
else if((*p)->lchild == NULL) //左子树为空
{
q = *p;
*p = (*p)->rchild;
free(q);
}
else
{
q = *p;
s = (*p)->lchild;
while(s->rchild)
{
q = s;
s = s->rchild;
}
(*p)->data = s->data;
if(q != *p) //s指向要删除节点的直接前驱,且s没有右子树(可模拟试试)
{
q->rchild = s->lchild;
}
else
{
q->lchild = s->lchild;
}
free(s);
}
}
return 1;
}
//删除一个节点的操作
int DeleteBST(BiTree *T,ElemType key)
{
if(!*T)
{
return 0;
}
else
{
if(key == (*T)->data)
{
return Delete(T);
}
else
{
if(key < (*T)->data)
{
return DeleteBST(&(*T)->lchild,key);
}
else
{
return DeleteBST(&(*T)->rchild,key);
}
}
}
}
按数据结构书本,难点是删除操作:
当删除节点左子树或右子树为空,则直接删除,修改其父节点右左指针。
当删除节点左右子树均不为空,有两种方法:
1.将删除节点的直接前驱代替(中序遍历),并将前驱节点的左孩子放其父节点右孩子位置。
2.将删除节点的左子树放其父节点左子树位置,将其右子树放其直接前驱右子树位置。(其实不难)
/***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int key;
struct node *lchild,*rchild;
}BSTNode;
//二叉排序树插入操作递归算法
BSTNode *InsertBST1(BSTNode *T, int key)
{
BSTNode *p, *q = T;
//p为待插入的新结点
p = (BSTNode *)malloc(sizeof(BSTNode));
p->key = key;
p->lchild = p->rchild = NULL;
if(T == NULL) //原树为空
T = p; //新插入的结点为新的根
//原树非空时将新结点p作为q的左孩子或右孩子插入
else
{
if(key == q->key)
return T;
if(key < q->key)
{
if(q->lchild ==NULL)
q->lchild = p;
else
InsertBST1(q->lchild, key);
}
if(key > q->key)
{
if(q->rchild ==NULL)
q->rchild = p;
else
InsertBST1(q->rchild, key);
}
}
return T;
}
二叉排序树插入操作非递归算法
BSTNode *InsertBST2(BSTNode *T, int key)
{
BSTNode *f, *p = T;
//查找插入位置
while(p)
{
if(key == p->key)
return T;//无须插入
f = p;//记录访问的结点
if(key < p->key)
p = p->lchild;
else
p = p->rchild;
//若key<p->key,则在左子树中查找,否则在右子树中查找
}
//p为待插入的新结点
p = (BSTNode *)malloc(sizeof(BSTNode));
p->key = key;
p->lchild = p->rchild = NULL;
if(T == NULL) //原树为空
T = p; //新插入的结点为新的根
//原树非空时将新结点q作为p的左孩子或右孩子插入
else
{
if(key < f->key)
f->lchild = p;
else f->rchild = p;
}
return T;
}
//二叉排序树删除操作
void DelBST(BSTNode *T,int key)
{
BSTNode *p = T, *f, *q, *s;
while(p)
{
if(p->key == key) break; //找到关键字为key的结点
f=p;//记下关键字key节点的父节点
p=(key < p->key)? p->lchild : p->rchild;//分别在*p的左、右子树中查找
}
if(!p) return;//二叉排序树中无关键字为key的结点
if(p->lchild == NULL && p->rchild == NULL)//p无左子树无右子树
{
if(p == T) T = NULL;//删除的是根节点
else
if(p == f->lchild)
f->lchild = NULL;
else
f->rchild = NULL;
}
else if(p->lchild == NULL && p->rchild != NULL)//p无左子树有右子树
{
if(f->lchild == p)
f->lchild = p->rchild;
else
f->rchild = p->rchild;
}
else if(p->rchild == NULL && p->lchild != NULL)//p有左子树无右子树
{
if (f->lchild == p)
f->lchild = p->lchild;
else
f->rchild = p->lchild;
}
else if(p->lchild != NULL && p->rchild != NULL)//p既有左子树又有右子树
{
q = p;
s = p->lchild;//转左
while(s->rchild)
{//然后向右到尽头
q = s;
s = s->rchild;//s指向被删节点的“前驱”(中序前驱)
}
p->key = s->key;//以p的中序前趋结点s代替p(即把s的数据复制到p中)
if(q != p)
q->rchild = s->lchild;//重接q的右子树
else
q->lchild = s->lchild;//重接q的左子树。
}
}
//创建二叉排序树
BSTNode *CreateBST()
{
BSTNode *T = NULL; //初始时T为空树
int key;
printf("请输入一系列数,以0结尾:");
while(1)
{
scanf("%d", &key);//读入一关键字
if(key == 0)
break;//假设key=0是输入结束标志
else
T = InsertBST1(T, key); //使用递归算法,将key插入二叉排序树T,改为 T = InsertBST2(T, key);为非递归插入算法
}
return T; //返回建立的二叉排序树的根指针
}
//二叉排序树查找递归算法
int BSTsearch1(BSTNode *T, int data)
{
BSTNode *p = T;
if(!p)
return 0;
else if(p->key == data)
return 1;
else if(p->key > data)
return BSTsearch1(p->lchild, data);
else
return BSTsearch1(p->rchild, data);
}
//二叉排序树查找非递归算法
int BSTsearch2(BSTNode *T, int data)
{
BSTNode *p = T;
while(p)
{
if(p->key == data)
return 1;
p = (p->key > data)? p->lchild : p->rchild;
}
return 0;
}
//中序遍历得到的是一个有序的序列,实现了排序功能
void Inorder(BSTNode *T)
{
if(T)
{
Inorder(T->lchild);
printf("%d ",T->key);
Inorder(T->rchild);
}
}