二叉排序树
创建二叉树,并将数据插入到结点中。程序执行后会将原数据进行从小到大排序,并输出排序结果
//定义数组source,并设置数组里面的数据。然后定义函数InsertBST(),用于在二叉树排序插入关键字key。首先查找要插入数据的父结点,然后根据插入数据的key于父结点值的大小,决定将结点插入到父结点的左子树还是右子树。
#include<stdio.h>
#include <malloc.h>
#include<stdlib.h>
#include<conio.h>
#define ARRAYLEN 10
int source[]={6,12,28,337,54,65,69,83,90,92};
typedef struct bst
{
int data;
struct bst *left;
struct bst *right;
}BSTree;
void InsertBST(BSTree *t,int key) //在二叉排序树中插入查找关键字key
{
BSTree *p,*parent,*head;
if(!(p=(BSTree *)malloc(sizeof(BSTree *)))) //申请内存空间
{
printf("申请内存出错!");
exit(0);
}
p->data=key; //保存结点数据
p->left=p->right=NULL; //左右子树置空
head=t;
while(head) //查找需要添加的父结点
{
parent=head;
if(key<head->data) //若关键字小于结点的数据
head=head->left; //在左子树上查找
else //若关键字大于结点的数据
head=head->left; //在右子树上查找
}
//判断添加到左子树还是右子树
if(key<parent->data) //小于父结点
parent->left=p; //添加到左子树
else //大于父结点
parent->right=p; //添加到右子树
}
//定义函数createBST(),将数组中的数据全部插入到二叉排序树中。
void CreateBST(BSTree *t,int data[],int n) //n个数据在数组d中,tree为二叉排序树根
{
int i;
t->data=data[0];
t->left=t->right=NULL;
for(i=1;i<n;i++)
{
InsertBST(t,data[i]);
}
}
//定义函数BST_LDR,这是一个中序遍历二叉树程序,能够检查二叉排序树是否成功。
void BST_LDR(BSTree *t) //中序遍历
{
if(t) //树不为空,则执行如下操作
{
BST_LDR(t->left); //中序遍历左子树
printf("%d",t->data); //输出结点数据
BST_LDR(t->right); //中序遍历右子树
}
return ;
}
//定义主函数main()用于输出测试结果
int main()
{
int key,i;
printf("原数据表:");
for(i=0;i<ARRAYLEN;i++)
printf("%d ",source[i]);
printf("\n");
CreateBST(&bst,source,ARRAYLEN);
printf("遍历二叉树排序树:");
BST_LDR(&bst);
getchar();
return 0;
}
删除结点
#include<stdio.h>
#include <malloc.h>
#include<stdlib.h>
#include<conio.h>
#define ARRAYLEN 10
int source[]={6,12,28,337,54,65,69,83,90,92};
typedef struct bst
{
int data;
struct bst *left;
struct bst *right;
}BSTree;
void InsertBST(BSTree *t,int key) //在二叉排序树中插入查找关键字key
{
BSTree *p,*parent,*head;
if(!(p=(BSTree *)malloc(sizeof(BSTree *)))) //申请内存空间
{
printf("申请内存出错!");
exit(0);
}
p->data=key; //保存结点数据
p->left=p->right=NULL; //左右子树置空
head=t;
while(head) //查找需要添加的父结点
{
parent=head;
if(key<head->data) //若关键字小于结点的数据
head=head->left; //在左子树上查找
else //若关键字大于结点的数据
head=head->left; //在右子树上查找
}
//判断添加到左子树还是右子树
if(key<parent->data) //小于父结点
parent->left=p; //添加到左子树
else //大于父结点
parent->right=p; //添加到右子树
}
//定义函数createBST(),将数组中的数据全部插入到二叉排序树中。
void CreateBST(BSTree *t,int data[],int n) //n个数据在数组d中,tree为二叉排序树根
{
int i;
t->data=data[0];
t->left=t->right=NULL;
for(i=1;i<n;i++)
{
InsertBST(t,data[i]);
}
}
//定义函数BST_LDR,这是一个中序遍历二叉树程序,能够检查二叉排序树是否成功。
void BST_LDR(BSTree *t) //中序遍历
{
if(t) //树不为空,则执行如下操作
{
BST_LDR(t->left); //中序遍历左子树
printf("%d ",t->data); //输出结点数据
BST_LDR(t->right); //中序遍历右子树
}
return ;
}
//删除结点
void BST_Delete(BSTree *t,int key)
{
BSTree *p,*parent,*l,*ll;
int child=0; //0表示左子树,1表示右子树
if(!t) //二叉排序树为空,则退出
return ;
p=t;
parent=p;
while(p)
{
if(p->data==key)
{
if(!p->left&&!p->right) //叶结点(左右子树都为空)
{
if(p==t) //被删除得是根结点
{
free(p); //释放被删除结点
}
else if(child==0) //父结点为左子树
{
parent->left=NULL; //设置父结点为左子树为空
free(p); //释放结点空间
}
else
{
parent->right=NULL; //设置父结点为右子树为空
free(p);
}
}
else if(!p->left) //左子树为空,右子树不为空
{
if(child==0) //是父结点的左子树
parent->left=parent->right;
else //是父结点的右子树
parent->left=p->left;
free(p); //释放被删除结点
}
else if(!p->right) //右子树为空,左子树不为空
{
if(child==0) //是父结点的左子树
parent->right=p->right;
else //父结点为右子树
parent->right=p->left;
free(p); //释放被删除结点
}
else //左右子树都不为空
{
ll=p; //保存左子树的父结点
l=p->right; //从当前结点的右子树进行查找
while(l->left) //左子树不为空
{
ll=l;
l=l->left; //查找左子树
}
p->data=l->data; //将左子树的数据保存到被删除的结点
ll->left=NULL; //设置父结点的左子树指针为空
free(ll); //释放左子树占的内存空间
}
p=NULL;
}
else if(key<p->data) //需删除记录的关键字小于结点的关键字
{
child=0; //标记在当前结点左子树查找
parent=p; //保存当前结点作父结点
p=p->left; //查找左子树
}
else //需删除记录的关键字大于结点的关键字
{
child=1; //标记在当前结点右子树查找
parent=p; //保存当前结点作父结点
p=p->right; //查找右子树
}
}
}
//定义主函数main()用于输出测试结果
int main()
{
int i;
BSTree bst;
printf("原数据表:");
for(i=0;i<ARRAYLEN;i++)
printf("%d ",source[i]);
printf("\n");
CreateBST(&bst,source,ARRAYLEN);
printf("遍历二叉树排序树:");
BST_LDR(&bst);
BST_Delete(&bst,54);
printf("\n删除结点后的结点:");
BST_LDR(&bst);
getchar();
return 0;
}
二叉排序树的查找
#include<stdio.h>
#include <malloc.h>
#include<stdlib.h>
#include<conio.h>
#define ARRAYLEN 10
int source[]={6,12,28,337,54,65,69,83,90,92};
typedef struct bst
{
int data;
struct bst *left;
struct bst *right;
}BSTree;
void InsertBST(BSTree *t,int key) //在二叉排序树中插入查找关键字key
{
BSTree *p,*parent,*head;
if(!(p=(BSTree *)malloc(sizeof(BSTree *)))) //申请内存空间
{
printf("申请内存出错!");
exit(0);
}
p->data=key; //保存结点数据
p->left=p->right=NULL; //左右子树置空
head=t;
while(head) //查找需要添加的父结点
{
parent=head;
if(key<head->data) //若关键字小于结点的数据
head=head->left; //在左子树上查找
else //若关键字大于结点的数据
head=head->left; //在右子树上查找
}
//判断添加到左子树还是右子树
if(key<parent->data) //小于父结点
parent->left=p; //添加到左子树
else //大于父结点
parent->right=p; //添加到右子树
}
//定义函数createBST(),将数组中的数据全部插入到二叉排序树中。
void CreateBST(BSTree *t,int data[],int n) //n个数据在数组d中,tree为二叉排序树根
{
int i;
t->data=data[0];
t->left=t->right=NULL;
for(i=1;i<n;i++)
{
InsertBST(t,data[i]);
}
}
//定义函数BST_LDR,这是一个中序遍历二叉树程序,能够检查二叉排序树是否成功。
void BST_LDR(BSTree *t) //中序遍历
{
if(t) //树不为空,则执行如下操作
{
BST_LDR(t->left); //中序遍历左子树
printf("%d ",t->data); //输出结点数据
BST_LDR(t->right); //中序遍历右子树
}
return ;
}
//删除结点
void BST_Delete(BSTree *t,int key)
{
BSTree *p,*parent,*l,*ll;
int child=0; //0表示左子树,1表示右子树
if(!t) //二叉排序树为空,则退出
return ;
p=t;
parent=p;
while(p)
{
if(p->data==key)
{
if(!p->left&&!p->right) //叶结点(左右子树都为空)
{
if(p==t) //被删除得是根结点
{
free(p); //释放被删除结点
}
else if(child==0) //父结点为左子树
{
parent->left=NULL; //设置父结点为左子树为空
free(p); //释放结点空间
}
else
{
parent->right=NULL; //设置父结点为右子树为空
free(p);
}
}
else if(!p->left) //左子树为空,右子树不为空
{
if(child==0) //是父结点的左子树
parent->left=parent->right;
else //是父结点的右子树
parent->left=p->left;
free(p); //释放被删除结点
}
else if(!p->right) //右子树为空,左子树不为空
{
if(child==0) //是父结点的左子树
parent->right=p->right;
else //父结点为右子树
parent->right=p->left;
free(p); //释放被删除结点
}
else //左右子树都不为空
{
ll=p; //保存左子树的父结点
l=p->right; //从当前结点的右子树进行查找
while(l->left) //左子树不为空
{
ll=l;
l=l->left; //查找左子树
}
p->data=l->data; //将左子树的数据保存到被删除的结点
ll->left=NULL; //设置父结点的左子树指针为空
free(ll); //释放左子树占的内存空间
}
p=NULL;
}
else if(key<p->data) //需删除记录的关键字小于结点的关键字
{
child=0; //标记在当前结点左子树查找
parent=p; //保存当前结点作父结点
p=p->left; //查找左子树
}
else //需删除记录的关键字大于结点的关键字
{
child=1; //标记在当前结点右子树查找
parent=p; //保存当前结点作父结点
p=p->right; //查找右子树
}
}
}
BSTree *SearchBST(BSTree *t,int key)
{
if(!t||t->data==key) //结点为空,或关键字相等
return t;
else if(key>t->data) //关键字大于结点数据
return(SearchBST(t->right,key));
else
return(SearchBST(t->left,key));
}
int main()
{
int i,key;
BSTree bst,*pos;
printf("原数据表:");
for(i=0;i<ARRAYLEN;i++)
printf("%d ",source[i]);
printf("\n");
CreateBST(&bst,source,ARRAYLEN);
printf("遍历二叉树排序树:");
BST_LDR(&bst);
BST_Delete(&bst,54);
printf("\n删除结点后的结点:");
BST_LDR(&bst);
printf("\n输入关键字:");
scanf("%d",&key);
pos=SearchBST(&bst,key);
if(pos)
printf("查找成功,该结点的地址:%x\n",pos);
else
printf("查找失败!\n");
getchar();
return 0;
}