C语言实现二叉查找树(BST)的基本操作
作者:乞力马扎罗的雪 发布时间:[ 2016/10/9 13:53:18 ] 推荐标签:二叉树 C语言
(5)查找元素
//查找某一个值
//返回1表示找到该值,返回0表示没有找到
BiTNode *SearchValue(BiTree T,int x){
if (T == NULL) {
return 0;
}else{
if (x < T->data) {
//查左子树
SearchValue(T->lChild, x);
}else if (x > T->data){
//查右子树
SearchValue(T->rChild, x);
}else{
//找到该值
printf("该值的内存地址为:%p ",T);
return T;
}
}
return NULL;
}
(6)删除元素
//删除某一个元素
BiTree *DeleteValue(BiTree *T,int x){
//先要查找该节点,同时也要保存该节点的父节点
BiTNode *searchNode;
BiTNode *parentNode;
//初始都指向根节点
searchNode = *T;
parentNode = *T;
while (searchNode->data != x) {
if (searchNode->lChild == NULL && searchNode->rChild == NULL) {
//已经是叶子节点了,但是还没有找到该值,表示树种根本没有要删除的节点
printf("%s函数执行,不存在该值,删除失败 ",__FUNCTION__);
return T;
}
if (x < searchNode->data) {
parentNode = searchNode;
searchNode = searchNode->lChild;
}else if (x > searchNode->data){
parentNode = searchNode;
searchNode = searchNode->rChild;
}else{
break;
}
}
if (searchNode->lChild == NULL && searchNode->rChild == NULL) {
//是叶子节点
if ((*T)->lChild == NULL && (*T)->rChild == NULL) {
//是根节点
free(*T);
*T = NULL;
}else{
//不是根节点,是普通的叶子节点
//需要判断要删除的节点是父节点的左孩子还是右孩子
if (searchNode->data < parentNode->data) {
//是左孩子
parentNode->lChild = NULL;
}else{
//是右孩子
parentNode->rChild = NULL;
}
free(searchNode);
searchNode = NULL;
}
return T;
}
if (searchNode->lChild != NULL && searchNode->rChild == NULL) {
//有左子树,没有右子树
//直接把父节点的指针指向右子树即可,然后释放自己;
//首先需要判断当前节点是父节点的左孩子还是右孩子
if (searchNode->data < parentNode->data) {
//是左孩子
parentNode->lChild = searchNode->lChild;
}else{
//是右孩子
parentNode->rChild = searchNode->lChild;
}
free(searchNode);
searchNode = NULL;
return T;
}
if (searchNode->lChild == NULL && searchNode->rChild != NULL) {
//没有左子树,有右子树
if (searchNode->data < parentNode->data) {
//是左孩子
parentNode->lChild = searchNode->rChild;
}else{
//是右孩子
parentNode->rChild = searchNode->rChild;
}
free(searchNode);
searchNode = NULL;
return T;
}
if (searchNode->lChild != NULL && searchNode->rChild != NULL) {
//要删除的节点既有左孩子,又有右孩子
/**
* 算法:删除节点p的左子树和右子树均不为空。找到p的后继y,因为y一定没有左子树,所以可以删除y,并让y的父节点成为y的右子树的父节点,并用y的值代替p的值;
如何找到要删除节点的后继节点,包括该后继节点的父节点!!
*/
BiTNode *nextNode;//寻找要删除节点的后继节点
BiTNode *nextParentNode;//寻找要删除节点的后继节点的父节点
nextParentNode = searchNode;
nextNode = searchNode->rChild;
while (nextNode->lChild != NULL) {
nextParentNode = nextNode;
nextNode = nextNode->lChild;
}
//这里要判断nextNode节点和nextParentNode节点的值大小,因为需要判断要删除节点是父亲的左孩子还是右孩子
if (nextNode->data < nextParentNode->data) {
//是左孩子
nextParentNode->lChild = nextNode->rChild;
}else{
//是右孩子
nextParentNode->rChild = nextNode->rChild;
}
//代替值
searchNode->data = nextNode->data;
//删除后继节点
free(nextNode);
nextNode = NULL;
return T;
}
return T;
}
(7)测试代码
int main(int argc, const char * argv[]) {
BiTree tree;
//这个是引用传递
CreateBinarySearchTree(&tree);
MiddleOrder(tree);
printf(" ");
printf("请输入要查找的元素:");
int searchValue;
scanf("%d",&searchValue);
SearchValue(tree,searchValue);
printf("请输入要删除的元素:");
int deleteValue;
scanf("%d",&deleteValue);
DeleteValue(&tree, deleteValue);
printf("先序遍历:");
PreOrder(tree);
printf(" 中序遍历:");
MiddleOrder(tree);//遍历检查
printf(" ");
return 0;
}
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南