数据结构C语言版_二叉排序树

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include
#include
/*
数据结构C语言版 二叉排序树
P227
编译环境:Dev-C++ 4.9.9.2
日期:2011年2月15日
*/

#define N 10 // 数据元素个数

typedef int KeyType; // 设关键字域为整型

typedef struct
{
KeyType key;
int others;
} ElemType; // 数据元素类型

typedef ElemType TElemType;

// 二叉树的二叉链表存储表示 动态查找表(二叉排序树)
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild; // 左右孩子指针
}BiTNode,*BiTree;

// 构造一个空的动态查找表DT
int InitDSTable(BiTree *DT)
{
*DT=NULL;
return 1;
}

// 销毁动态查找表DT
void DestroyDSTable(BiTree *DT)
{
if(*DT) // 非空树
{
if((*DT)->lchild) // 有左孩子
DestroyDSTable(&(*DT)->lchild); // 销毁左孩子子树
if((*DT)->rchild) // 有右孩子
DestroyDSTable(&(*DT)->rchild); // 销毁右孩子子树
free(*DT); // 释放根结点
*DT=NULL; // 空指针赋0
}
}

// 算法9.5(a) P228
// 在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素,
// 若查找成功,则返回指向该数据元素结点的指针,否则返回空指针。
BiTree SearchBST(BiTree T,KeyType key)
{
if((!T)|| (key == T->data.key))
return T; // 查找结束
else if(key < T->data.key) // 在左子树中继续查找
return SearchBST(T->lchild,key);
else
return SearchBST(T->rchild,key); // 在右子树中继续查找
}

// 算法9.5(b) P228
// 在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找
// 成功,则指针p指向该数据元素结点,并返回1,否则指针p指向查找路径上
// 访问的最后一个结点并返回0,指针f指向T的双亲,其初始调用值为NULL
void SearchBST1(BiTree *T,KeyType key,BiTree f,BiTree *p,int *flag)
{
if(!*T) // 查找不成功
{
*p = f;
*flag = 0;
}
else if(key == (*T)->data.key) // 查找成功
{
*p=*T; //指针p指向该数据元素结点
*flag=1;
}
else if(key < (*T)->data.key)
SearchBST1(&(*T)->lchild,key,*T,p,flag); // 在左子树中继续查找
else
SearchBST1(&(*T)->rchild,key,*T,p,flag); // 在右子树中继续查找
}

// 算法9.6 P228
// 当二叉排序树T中不存在关键字等于e.key的数据元素时,插入e并返回1,
// 否则返回0。
int InsertBST(BiTree *T, ElemType e)
{
BiTree p,s;
int flag;

SearchBST1(T,e.key,NULL,&p,&flag);
if(!flag) // 查找不成功
{
s=(BiTree)malloc(sizeof(BiTNode));
s->data=e;
s->lchild=s->rchild=NULL;
if(!p)
*T = s; // 被插结点*s为新的根结点
else if(e.key < p->data.key)
p->lchild = s; // 被插结点*s为左孩子,值小的在左边
else
p->rchild = s; // 被插结点*s为右孩子,值大的在右边
return 1;
}
else
return 0; // 树中已有关键字相同的结点,不再

插入
}

// 算法9.8 P231
// 从二叉排序树中删除结点p,并重接它的左或右子树。
void Delete(BiTree *p)
{
BiTree q, s;

// 右子树空则只需重接它的左子树(待删结点是叶子也走此分支)
if(!(*p)->rchild)
{
q=*p;
*p=(*p)->lchild;
free(q);
}
else if(!(*p)->lchild) // 只需重接它的右子树
{
q=*p;
*p=(*p)->rchild;
free(q);
}
else // 左右子树均不空
{
q=*p;
s=(*p)->lchild;
while(s->rchild) // 转左,然后向右到尽头(找待删结点的前驱)
{
q=s;
s=s->rchild;
}
// s指向被删结点的"前驱"(将被删结点前驱的值取代被删结点的值)
(*p)->data=s->data;
if(q!=*p)
q->rchild=s->lchild; // 重接*q的右子树
else
q->lchild=s->lchild; // 重接*q的左子树
free(s);
}
}

// 算法9.7 P230
// 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点,
// 并返回1;否则返回0。
int DeleteBST(BiTree *T,KeyType key)
{
if(!*T) // 不存在关键字等于key的数据元素
return 0;
else
{
if(key == (*T)->data.key) // 找到关键字等于key的数据元素
Delete(T);
else if(key < (*T)->data.key)
DeleteBST(&(*T)->lchild,key);
else
DeleteBST(&(*T)->rchild,key);
return 1;
}
}

// 按关键字的顺序对DT的每个结点调用函数Visit()一次
void TraverseDSTable(BiTree DT,void(*Visit)(ElemType))
{
if(DT)
{
// 像这样先序遍历,最后结果是个非递减顺序
TraverseDSTable(DT->lchild,Visit); // 先中序遍历左子树
Visit(DT->data); // 再访问根结点
TraverseDSTable(DT->rchild,Visit); // 最后中序遍历右子树
}
}

void print(ElemType c)
{
printf("(%d,%d) ",c.key,c.others);
}

int main()
{
BiTree dt,p;
int i;
KeyType j;

ElemType r[N]={
{45,1},{12,2},{53,3},{3,4},{37,5},{24,6},
{100,7},{61,8},{90,9},{78,10}
}; // 以教科书P227图9.7(a)为例
InitDSTable(&dt); // 构造空表
for(i=0;iInsertBST(&dt,r[i]); // 依次插入数据元素
TraverseDSTable(dt,print);
printf("\n请输入待查找的值: ");
scanf("%d",&j);
p=SearchBST(dt,j);
if(p)
{
printf("表中存在此值。");
DeleteBST(&dt,j);
printf("删除此值后:\n");
TraverseDSTable(dt,print);
printf("\n");
}
else
printf("表中不存在此值\n");
DestroyDSTable(&dt);

system("pause");
return 0;
}

/*
输出效果:

(3,4) (12,2) (24,6) (37,5) (45,1) (53,3) (61,8) (78,10) (90,9) (100,7)
请输入待查找的值: 61
表中存在此值。删除此值后:
(3,4) (12,2) (24,6) (37,5) (45,1) (53,3) (78,10) (90,9) (100,7)
请按任意键继续. . .

*/

相关文档
最新文档