标签:二叉排序树
使用c实现.
二叉排序树: 左子树小于根结点, 右子树大于根结点
因为二叉排序的特点 不难看出 中序遍历之后的结果就是有序的(从小到大)
搜索的时候如果大于根结点就遍历右子树,小于根结点就遍历左子树,否则就查找成功.
总结:
二叉排序树是链式方式存储,保持了链接存储结构在执行插入和删除操作是不用移动元素的优点, 只要找到合适的插入和删除位置后, 仅需要修改链接指针即可,
插入删除的时间性能比较好
超找的次数就是从根结点到要查找的结点的路径, 其比较次数等于给定结点在二叉树的层数,
最少查找次数是O(1), 做多也不会超过树的深度
所以查找的性能取决于二叉排序树的形状.
//二叉排序树
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef int Status;
//二叉树的结构体定义
typedef struct BiTNode{
int data;
struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode, *BiTree;
//二叉排序树的查找实现
/*
递归实现, 查找二叉排序树T中是否存在key
指针f是T的双亲, 初始值是null
查找成功,用指针p指向给数据的结点, 返回true
查找失败,指针p指向查找路径上最后一次访问的结点, 返回false
num 查找的次数
*/
Status searchBST(BiTree T, int key, BiTree f, BiTree *p, int *num){
(*num) ++;
if(!T){ //查找失败
*p = f;
return FALSE;
}else if(T->data == key){ //查找成功
*p = T;
return TRUE;
}else if(T->data > key){
searchBST(T->lchild, key, T, p, num); //在左子树中查找
}else{
searchBST(T->rchild, key, T, p, num); //在右子树中查找
}
}
//插入
/*
key不在树中,则插入
*/
insertBST(BiTree *T, int key){
BiTree p, s;
int num = 0;
if(!searchBST(*T, key, NULL, &p, &num)) { //查找不成功
s = (BiTree)malloc(sizeof(BiTNode));
s->data = key;
s->lchild = s->rchild = NULL;
if(!p){
*T = s; //根结点
}else if(p->data > key){ //新的结点插入到左子树中
p->lchild = s;
} else{
p->rchild = s;
}
return TRUE;
}
return FALSE;
}
//中序遍历二叉排序树
void inOrderTraverse(BiTree T){
if(T == NULL){
return;
}
inOrderTraverse(T->lchild);
printf("%d ", T->data);
inOrderTraverse(T->rchild);
}
//前序遍历二叉排序树
void preOrderTraverse(BiTree T){
if(T == NULL){
return;
}
printf("%d ", T->data);
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
//后序遍历二叉排序树
void postOrderTraverse(BiTree T){
if(T == NULL){
return;
}
postOrderTraverse(T->lchild);
postOrderTraverse(T->rchild);
printf("%d ", T->data);
}
//二叉排序树的删除 重构左右子树
Status 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{ //左右子树都不为null
q = *p;
s = (*p)->lchild;
while(s->rchild){ //找左子树的最大值
q = s;
s = s->rchild;
}
(*p)->data = s->data; //将s的值直接覆盖要删除的结点
if(q != *p){
q->rchild = s->lchild; //重构q的右子树
} else{
q->rchild = s->lchild; //重构q的左子树
}
free(s);
}
return TRUE;
}
//二叉排序树的删除 找结点
/*
二叉排序树中存在关键字是key的则删除 元素结点 返回true否则返回false
*/
Status deleteBST(BiTree *T, int key){
if(!*T){
return FALSE; //不存在关键字key的数据元素
}else{
if((*T)->data == key){
return delete(T);
}else if((*T)->data > key){
return deleteBST(&((*T)->lchild), key);
} else{
return deleteBST(&((*T)->rchild), key);
}
}
}
//遍历
void travese(BiTree T){
printf("前序遍历是: ");
preOrderTraverse(T);
printf("\n");
printf("中序遍历是: ");
inOrderTraverse(T);
printf("\n");
printf("后序遍历是: ");
postOrderTraverse(T);
printf("\n");
}
Status main(void){
BiTree T = NULL, p;
int arr[10] = {1,34,3,234,2,6,343,43,4,32};
int i;
for(i = 0; i < 10 ; i ++){
insertBST(&T, arr[i]);
}
int option = 1, key = 0, res = 0, num = 0;
printf(" 1. 查找数据\n 2. 遍历数据\n 3. 删除数据\n 0. 退出\n");
while(option){
scanf("%d", &option);
switch(option){
case 1:
num = 0;
printf("请输入要查找的数据\n");
scanf("%d", &key);
res = searchBST(T, key, NULL, &p, &num);
if(res == TRUE){
printf("查找成功 查找的次数是: %d\n", num);
}else{
printf("查找失败 查找的次数是: %d\n", num);
}
break;
case 2:
travese(T);
break;
case 3:
printf("请输入要删除的数据\n");
scanf("%d", &key);
res= deleteBST(&T, key);
if(res == TRUE){
printf("删除成功\n");
travese(T);
}else{
printf("删除失败 删除的数据不存在\n");
}
break;
case 0:
return TRUE;
break;
default:
printf(" 1. 查找数据\n 2. 遍历数据\n 0. 退出\n");
break;
}
}
return TRUE;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:二叉排序树
原文地址:http://blog.csdn.net/u010187139/article/details/47125803