二叉查找树实现:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define malloc_thing(thing) (thing *)malloc(sizeof(thing))
//此函数指针用来插入时做比较使用
typedef int (*tree_compare_t)(void *node_value,void *insert_value);
typedef struct tree_node_t tree_node_t;
typedef struct tree_t tree_t;
//树节点结构
struct tree_node_t
{
tree_node_t *left; //左子树
tree_node_t *right; //右子树
void *value; //存储的值
};
//树结构
struct tree_t
{
tree_node_t *root; //树根
unsigned int count; //节点数
tree_compare_t compare; //节点比较方法
};
///////////////////////////////////////////////////////
//创建一个节点
tree_node_t *tree_node_create(void *value)
{
tree_node_t *node=malloc_thing(tree_node_t);
node->value=value;
node->left=NULL;
node->right=NULL;
return node;
}
//节点销毁
void tree_node_destroy(tree_node_t *node)
{
free(node);
}
//销毁子树
void tree_all_node_destroy(tree_node_t *node)
{
if(node!=NULL)
{
tree_all_node_destroy(node->left);
tree_all_node_destroy(node->right);
tree_node_destroy(node);
}
}
//子树最大值
tree_node_t *tree_node_max(tree_node_t *node)
{
while(node->right!=NULL)
{
node=node->right;
}
return node;
}
//子树最小值
tree_node_t *tree_node_min(tree_node_t *node)
{
while(node->left!=NULL)
{
node=node->left;
}
return node;
}
//递归插入一个节点
/*
算法解释:
插入一个节点,首先要看是否已经存在,也就是先查找,
所以要不断的递归进行比较。
(1)如果一直到NULL,也就是没有找到,说明插入的为新节点,
需要创建新的节点。
(2)如果相等,说明已经存在,不需要再插入了,则返回即可
(3)如果不相等,根据大小插入节点的左子树或者右子树
*/
tree_node_t *tree_node_insert(tree_t *tree,tree_node_t *node,void *value)
{
//节点为空表明已经查找到了叶子,插入的值为新值,需要创建新的节点
if(node==NULL)
{
tree->count++;
tree_node_t *node=tree_node_create(value);
return node;
}
//如果插入值等于节点值,说明已经存在,无需插入,直接返回
else if(tree->compare(node->value,value)==0)
{
return node;
}
//如果插入值大于节点值,继续往右子树插入
else if(tree->compare(node->value,value)<0)
{
node->right=tree_node_insert(tree,node->right,value);
return node;
}
//如果插入值小于节点值,继续往左子树插入
else
{
node->left=tree_node_insert(tree,node->left,value);
return node;
}
}
// 递归删除一个节点
/*
算法解释:
删除一个节点,删除和插入很像,不过要复杂点。
也要先查找点,不过找到要执行删除操作,没找到反而不用干什么。
(1)如果为NULL,说明没找到,只要返回NULL就行了
(2)如果相等,说明已经存在要删除的节点,那就需要删除此节点了
1)如果此节点左右子树都为空,那就直接删除节点,返回NULL就行
2)如果此节点左子树不空,而右子树为空,删除节点,返回左子树
3)如果此节点右子树不空,而左子树为空,删除节点,返回右子树
4)如果左右子树都不空,那就需要早到左子树中最大的数或则右子树
中最小的值,替换到要删除的值,然后在左子树中删除最大的节点
或者右子树删除最小的节点。
(3)如果不相等,根据大小删除节点
*/
tree_node_t *tree_node_delete(tree_t *tree,tree_node_t *node,void *value)
{
//如果为NULL,说明没找到,只要返回NULL就行了
if(node==NULL)
{
return NULL;
}
//如果相等,说明已经存在要删除的节点,那就需要删除此节点了
else if(tree->compare(node->value,value)==0)
{
tree_node_t *left=node->left;
tree_node_t *right=node->right;
//如果此节点左右子树都为空,那就直接删除节点,返回NULL就行
if(!left&&!right)
{
tree_node_destroy(node);
return NULL;
}
//如果此节点左子树不空,而右子树为空,删除节点,返回左子树
else if(left&&!right)
{
tree_node_destroy(node);
return left;
}
//如果此节点右子树不空,而左子树为空,删除节点,返回右子树
else if(!left&&right)
{
tree_node_destroy(node);
return right;
}
//如果左右子树都不空,那就需要早到左子树中最大的数
//替换到要删除的值
//然后在左子树中删除最大的节点
//返回节点
else
{
tree_node_t *max=tree_node_max(left);
node->value=max->value;
node->left =tree_node_delete(tree,left,max->value);
return node;
}
}
//如果不相等,根据大小删除节点
else if(tree->compare(node->value,value)<0)
{
node->right=tree_node_delete(tree,node->right,value);
return node;
}
else
{
node->left=tree_node_delete(tree,node->left,value);
return node;
}
}
// 递归查找一个节点
tree_node_t *tree_node_search(tree_t *tree,tree_node_t *node,void *value)
{
//如果为NULL,说明没找到,只要返回NULL就行了
if(node==NULL)
{
return NULL;
}
//如果相等,说明已经存在要删除的节点,那就需要删除此节点了
else if(tree->compare(node->value,value)==0)
{
return node;
}
//如果不相等,根据大小删除节点
else if(tree->compare(node->value,value)<0)
{
return tree_node_search(tree,node->right,value);
}
else
{
return tree_node_search(tree,node->left,value);
}
}
//打印结构 ---先序遍历
void display_tree_node(tree_node_t *node)
{
if(node!=NULL)
{
printf(" [ %d ] ",*((int *)node->value));
display_tree_node(node->left);
display_tree_node(node->right);
}
}
/////////////////////////////////////////////////////////
/*下面的方法才是对外的方法*/
//创建一棵树
tree_t *tree_create(tree_compare_t compare)
{
tree_t *tree=malloc_thing(tree_t);
tree->root=NULL;
tree->count=0;
tree->compare=compare;
return tree;
}
//向树种插入一个节点
void tree_insert(tree_t *tree,void *value)
{
tree->root=tree_node_insert(tree,tree->root,value);
}
//向树中删除一个节点
void tree_delete(tree_t *tree,void *value)
{
tree->root=tree_node_delete(tree,tree->root,value);
}
//向树中删除一个节点
void * tree_search(tree_t *tree,void *value)
{
tree_node_t *node=tree_node_search(tree,tree->root,value);
if(node!=NULL)
{
return node->value;
}
else
{
return NULL;
}
}
//销毁此树
void tree_destroy(tree_t *tree)
{
if(tree->root!=NULL)
{
tree_all_node_destroy(tree->root);
}
free(tree);
}
//打印树,用来查看我们的树
void display_tree(tree_t *tree)
{
display_tree_node(tree->root);
printf("\n");
}
////////////////////////////////////////////////////
int tree_compare(int *node_value,int *insert_value)
{
int a=*node_value;
int b=*insert_value;
if(a==b)
{
return 0;
}
else if(a>b)
{
return 1;
}
else
{
return -1;
}
}
main()
{
tree_t *tree=tree_create((tree_compare_t)tree_compare);
int a=1;
int b=2;
int c=3;
int d=0;
int e=5;
//插入a
printf("插入%d:",a);
tree_insert(tree,&a);
display_tree(tree);
printf("插入%d:",a);
tree_insert(tree,&a);
display_tree(tree);
printf("插入%d:",b);
tree_insert(tree,&b);
display_tree(tree);
printf("插入%d:",c);
tree_insert(tree,&c);
display_tree(tree);
printf("插入%d:",d);
tree_insert(tree,&d);
display_tree(tree);
//查找
if(tree_search(tree,&a)!=NULL)
{
printf("查找%d: 找到\n",a);
}
else
{
printf("查找%d: 没有找到\n",a);
}
//查找
if(tree_search(tree,&e)!=NULL)
{
printf("查找%d: 找到",e);
}
else
{
printf("查找%d: 没有找到\n",e);
}
//删除节点a
printf("删除%d:",a);
tree_delete(tree,&a);
display_tree(tree);
//删除节点c
printf("删除%d:",c);
tree_delete(tree,&c);
display_tree(tree);
//删除节点d
printf("删除%d:",d);
tree_delete(tree,&d);
display_tree(tree);
//删除节点b
printf("删除%d:",b);
tree_delete(tree,&b);
display_tree(tree);
//删除节点a
printf("删除%d:",a);
tree_delete(tree,&a);
display_tree(tree);
tree_destroy(tree);
system("pause");
}
分享到:
相关推荐
二叉查找树(Binary Search Tree,BST)是一种特殊的...不过,由于没有具体的代码示例,这里只能给出一个通用的二叉查找树的C++实现框架。如果你想要更详细的C语言实现,或者关于C++代码的特定部分,可以进一步询问。
在C语言中实现二叉查找树,我们需要定义一个结构体来表示树节点,包含节点的值以及指向左右子节点的指针。例如: ```c typedef struct Node { int data; struct Node* left; struct Node* right; } Node; ``` ...
用C++实现的最优二叉查找树,简单,明了,是数据结构里经典必学算法,初学者适用
1、 定义二叉查找树的类。 2、 实验验证如下算法的正确性、各种功能及指标: 1)实现二叉查找树结构; 2) 实现二叉查找树的查找、插入和删除等算法;
在提供的`searchTree`源码中,应该包含了对这些操作的详细实现,你可以通过阅读和理解代码来学习如何在C语言中操作二叉查找树。这将有助于你深入理解数据结构和算法,为今后的编程工作打下坚实的基础。
在提供的`main.c`文件中,很可能包含了实现AVL树的C语言代码。`README.txt`可能是对代码的简要说明或使用指南,包含有关如何编译和运行程序的信息。通过阅读这些文件,可以深入理解AVL树的数据结构和操作细节。在...
这种特性使得二叉排序树在查找、插入和删除操作上具有较高的效率。 在C语言中,二叉排序树可以通过结构体来表示。以下是一个简单的二叉排序树节点结构体定义: ```c typedef struct BiTNode { char data; // 数据...
在"lab1_BT"这个实验文件中,很可能是包含了实现上述功能的源代码,你可以通过阅读和分析这些代码来深入理解二叉查找树的工作原理和Objective-C的编程实践。同时,这个程序也可以作为一个学习和教学的工具,帮助初学...
这些基本操作是构建高效数据结构的基础,理解并熟练掌握二叉查找树的实现,对提升算法能力和编写高效代码至关重要。在实际应用中,二叉查找树常用于数据库索引、文件系统等场景,其性能优势在于能够快速定位和访问...
读一个文件,文件中包含2000个以上英文名字 利用二叉数进行查找,在查找过程中避免 冲突的代码
本篇内容将深入解析Python在LeetCode面试中的第99题——恢复二叉搜索树(Recover Binary Search Tree)。 二叉搜索树(Binary Search Tree,BST)是一种特殊的二叉树,它的每个节点都满足以下性质:左子树上所有...
在"ABR.zip_abr_二叉查找树"压缩包中,包含三个文件:tree.c、main.c和tree.h,它们分别用于实现二叉查找树的函数、主程序和头文件定义。 `tree.c` 文件通常包含了二叉查找树的主要功能实现,如创建新节点、插入...
二叉排序树(Binary Search Tree, BST),又称为二叉查找树或有序二叉树,是一种特殊的二叉树数据结构。它具有以下性质: 1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 2. 若任意节点...
在C语言中实现二叉查找树时,通常需要定义一个结构体来表示节点。例如,可以定义如下的结构体: ```c typedef struct node { int data; struct node* lchild; struct node* rchild; } nodeb, *bitree; ``` 这里...
`BinTree.c`可能包含了二叉查找树的实现,包括节点的创建、查找、插入和删除等方法。`BinTree.exe`和"二叉查找树输出结果.PNG"则可能展示了运行时的树结构和操作结果。 总结来说,这个压缩包提供了一套关于三元组、...
二叉查找树(Binary Search Tree,BST)是一种特殊的二叉树结构,它的每个节点都包含一个键值(key)、一个关联...通过阅读和分析这些源代码,我们可以深入理解二叉查找树的内部机制,以及如何在C语言中有效地实现它。
二叉排序树,又称二叉查找树或二叉搜索树,是一种特殊的二叉树数据结构,它具有以下特性:对于树中的每个节点,其左子树中的所有节点的值都小于该节点的值,而右子树中的所有节点的值都大于该节点的值。这种性质使得...
本实验探讨了两种常见的自平衡二叉查找树——红黑树(Red-Black Tree)和二叉搜索树(Binary Search Tree),并用C语言实现了这两种数据结构,同时进行了性能比较。 首先,我们要理解二叉搜索树的基本特性。二叉...