《c和指针》笔记-简洁的二叉查找树删除node方法
来源:互联网 发布:绝地求生辅助网站源码 编辑:程序博客网 时间:2024/05/22 12:17
之前写过一个二叉查找树,其中最麻烦的是删除元素的方法,一共分了8种情况,主要是要区分是否是根节点和非根节点,
写的太烦了,详细请参见:http://blog.csdn.net/todd911/article/details/8471566
今天要来简化一下这个方法,之前我还写过一篇《简洁的单项链表插入操作》,利用双指针,简化了根节点和非根节点的区别,
详细请参见:http://blog.csdn.net/todd911/article/details/8941593,其实在二叉查找树中也可以使用这种方法。
改进后的代码如下:
void deleteNode(treeNode** node, int value){ treeNode* current; while( (current = *node) != NULL && current->value != value ){ if(current->value > value){ node = ¤t->left; }else if(current->value < value){ node = ¤t->right; } }//如果current为NULL,则没有找到 if(current == NULL){ printf("this node want to delete is not exit!\n"); }else{//如果找到节点,则判断节点的状态//没有孩子节点,则直接删除 if(current->left == NULL && current->right == NULL){ free(current); *node = NULL; current = NULL; }else //左右孩子都有,则先将右孩子插入到左孩子树上,再将原先指向current的指针指向current的左孩子,删除currentif(current->left != NULL && current->right != NULL){ insertNode(current->left, current->right); *node = current->left; free(current); current = NULL; }else //没有左孩子,有右孩子,则将原先指向current的指针指向current的右孩子,删除currentif(current->left == NULL && current->right != NULL){ *node = current->right; free(current); current = NULL; }else //没有右孩子,有左孩子,则将原先指向current的指针指向current的左孩子,删除currentif(current->left != NULL && current->right == NULL){ *node = current->left; free(current); current = NULL; } }}
这种方法有一个问题,就是被删除的节点都有左右孩子,就会先将右孩子插入到左孩子树上,再将原先指向current的指针指向current的左孩子,
导致二叉树的树干长度不平衡了。
详细步骤如下,节点12是要被删除的:
可见,最后树的结构破坏比较大, 可能会导致查找的效率降低。
下面我们来改进一下,如果要被删除的节点有左右孩子,则从左孩子获得值最大的那个,来替换要被删除的节点,详细步骤如下,节点12是要被删除的:
怎么样,树的结构没有怎么被破坏吧,推荐还是使用这种方法比较好。
下面附上完整的sample代码:
#include <stdio.h>#include <stdlib.h>#define SIZE 10typedef struct tagNode{ int value; struct tagNode* left; struct tagNode* right;}treeNode;void displayArray(int array[],int size){ printf("the array is:"); int i; for(i=0;i<size;i++){ printf("%d ",array[i]); } printf("\n");}void displayTree(treeNode* node){ if(node == NULL) return; if(node->left != NULL){ displayTree(node->left); } printf("%d ",node->value); if(node->right != NULL){ displayTree(node->right); }}void insertNode(treeNode* node, treeNode* iNode){ if(iNode->value >= node->value && node->right != NULL){ insertNode(node->right, iNode); return; } if(iNode->value < node->value && node->left != NULL){ insertNode(node->left, iNode); return; } if(iNode->value >= node->value && node->right == NULL){ node->right = iNode; } if(iNode->value < node->value && node->left == NULL){ node->left = iNode; }}void deleteNode(treeNode** node, int value){ treeNode* current; while( (current = *node) != NULL && current->value != value ){ if(current->value > value){ node = ¤t->left; }else if(current->value < value){ node = ¤t->right; } } if(current == NULL){ printf("this node want to delete is not exit!\n"); }else{ if(current->left == NULL && current->right == NULL){ free(current); *node = NULL; current = NULL; }else if(current->left != NULL && current->right != NULL){ insertNode(current->left, current->right); *node = current->left; free(current); current = NULL; }else if(current->left == NULL && current->right != NULL){ *node = current->right; free(current); current = NULL; }else if(current->left != NULL && current->right == NULL){ *node = current->left; free(current); current = NULL; } }}void getMaxValueNode(treeNode **link){ while( *link != NULL && (*link)->right != NULL){ *link = (*link)->right; };}void deleteNode2(treeNode** node, int value){ treeNode* current; while( (current = *node) != NULL && current->value != value ){ if(current->value > value){ node = ¤t->left; }else if(current->value < value){ node = ¤t->right; } } if(current == NULL){ printf("this node want to delete is not exit!\n"); }else{ if(current->left == NULL && current->right == NULL){ free(current); *node = NULL; current = NULL; }else if(current->left != NULL && current->right != NULL){ treeNode** link = ¤t->left; getMaxValueNode(link); if(*link != NULL){ treeNode *maxValueNode = *link; *link = (*link)->left; maxValueNode->left = current->left; maxValueNode->right = current->right; *node = maxValueNode; free(current); current = NULL; } }else if(current->left == NULL && current->right != NULL){ *node = current->right; free(current); current = NULL; }else if(current->left != NULL && current->right == NULL){ *node = current->left; free(current); current = NULL; } }}void createTree(treeNode** root, int array[], int size){ int i; *root = (treeNode*)malloc(sizeof(treeNode)); (*root)->value = array[0]; (*root)->left = NULL; (*root)->right = NULL; for(i=1;i<size;i++){ treeNode* child = (treeNode*)malloc(sizeof(treeNode)); child->value = array[i]; child->left = NULL; child->right = NULL; insertNode(*root, child); }}void deleteTree(treeNode* node){ if(node == NULL) return; if(node->left != NULL){ deleteTree(node->left); } if(node->right != NULL){ deleteTree(node->right); } if(node->left == NULL && node->right == NULL){ free(node); node = NULL; }}int main(int argc, char* argv[]){ int array[SIZE] = {60,4,45,78,345,23,12,3,6,21}; displayArray(array,SIZE); treeNode *root = NULL; createTree(&root, array, SIZE); printf("the tree is(left->middle->right):"); displayTree(root); printf("\n"); int value = 12; printf("delete value:%d\n",value); deleteNode(&root,value); printf("the tree is(left->middle->right):"); displayTree(root); printf("\n"); value = 78; printf("delete value:%d\n",value); deleteNode2(&root,value); printf("the tree is(left->middle->right):"); displayTree(root); printf("\n"); deleteTree(root); return 0;}
- 《c和指针》笔记-简洁的二叉查找树删除node方法
- 二叉查找树节点的查找、插入和删除
- 二叉查找树的查找、插入和删除
- 二叉树的建立、节点查找以及节点删除C和C++实现
- C语言实现二叉搜索树的创建、插入、删除和查找
- 二叉树的建立、节点查找以及节点删除C和C++实现
- 【c++】二叉搜索树的插入、查找、非递归删除
- 二叉查找树的删除
- 二叉树的查找删除
- 《c和指针》笔记--简洁的单项链表插入操作
- 二叉查找树的插入,删除,查找
- 二叉查找树的插入,删除,查找
- 二叉查找树的插入,删除,查找
- 简单的指针二叉查找树和数组二叉查找树
- 二叉查找树的插入和删除详解
- 二叉查找树的插入和删除简单实现
- 每天一点数据结构之二叉树的查找和删除
- 二叉搜索树(BST)的创建、插入、查找和删除
- 动态规划专项intermediate:UVa 11400
- LoadRunner压力测试结果分析探讨
- 性能问题定位及调优
- 杂题专项:UVa 818
- poj 3270 置换群
- 《c和指针》笔记-简洁的二叉查找树删除node方法
- Python Exercise #19
- linux内核同步之每CPU变量、原子操作、内存屏障、自旋锁
- 测试cpu的简单工具-dhrystone
- UVa 516-Prime Land
- 读写信号量,读写锁,顺序锁
- php学习(三)遍历数组的方法
- HDU/HDOJ 1253 胜利大逃亡 广度优先搜索算法 迷宫寻路
- 计算几何专项:UVa 588