BST二叉搜索树

xiaoxiao2021-02-28  104

BST的查找算法

//递归查找 struct node *Find(ElementType key,struct node *BST){ if(!BST) return NULL;//查找失败 if(key > BST->data){ return Find(key,BST->right); }else if(key < BST->data){ return Find(key,BST->left); }else{//key == BST->data return BST;//返回查找成功的结点的地址 } }

由于非递归函数的执行效率高,一般采用非递归的迭代方式来实现查找。

//迭代查找 struct node *IterFind(ElementType key,struct node *BST){ while(BST){ if(key > BST->data){ BST = BST->right; }else if(key < BST->data){ BST = BST->left; }else{//key == BST->data return BST;//返回查找成功的结点的地址 } } return NULL;//查找失败 }

查找最小元素

根据二叉搜索树的性质,最小元素一定在二叉树的最左分支的叶子结点上。同理,最大元素一定在二叉树的最右分支的叶子节点上。

//递归查找最小元素 struct node *FindMin(struct node *BST){ if(!BST) return NULL;//空的二叉树返回NULL if(!BST->left) return BST;//找到最左边结点 else return FindMin(BST->left);//沿着左分支继续查找 } //迭代查找最小元素 struct node *IterFindMin(struct node *BST){ if(BST){ while(BST->left){ BST = BST->left;//沿着左分支继续查找 } } return BST; }

BST的插入

//插入 struct node *Insert(ElementType key,struct node *BST){ //若原二叉树为空,则生成并返回一个结点的二叉搜索树 if(!BST){ BST = (struct node *)malloc(sizeof(struct node)); BST->data = key; BST->left = BST->right = NULL; }else if(key < BST->data){ BST->left = Insert(key,BST->left);//递归插入左子树 }else if(key > BST->data){ BST->right = Insert(key,BST->right);//递归插入右子树 } return BST; }

BST的删除

BST的删除分为三种情况: 1.待删除的结点是叶子结点: 直接删除,将指向该结点的指针置空即可 2.待删除的结点只有一个分支: 修改该结点的指针,将其指向为其孩子的结点。即上移子树。 3.待删除结点有左右两个分支: 这时有两种情况可以选择:用删除节点的直接前驱或者直接后继来替换当前结点,再递归删除直接前驱或者直接后继的结点位置。 (可能,十分绕口) 简而言之:一种就是选择其左子树的最大元素,另一种就是选择右子树的最小元素。 (注:用中序遍历一下上图的二叉树,你就知道为什么叫前驱元素和后继元素了。)

//删除 struct node *Delete(ElementType key,struct node *BST){ struct node *temp = NULL; if(!BST){ printf("要删除的元素未找到"); }else if(key < BST->data){ BST->left = Delete(key,BST->left); }else if(key > BST->data){ BST->right = Delete(key,BST->right);//找到要删除的结点 }else if(BST->left && BST->right){//被删除的结点有左右两个子结点 temp = FindMin(BST->right);//在右子树中找到最小的元素填充删除的结点 BST->data = temp->data; BST->right = Delete(BST->data,BST->right); }else if(BST->left){//被删除的结点只有左分支 BST = BST->left; }else if(BST->right){//被删除的结点只有右分支 BST = BST->right; }else{//被删除的结点无左右分支 BST = NULL; } return BST; }

缺陷

最好的情况是二叉排序树的形态和二分查找的判定树相同,其平均查找长度和log 2 (n)成正比。 最坏情况下,当先后插入的关键字有序时,构成的二叉排序树退化为单支树,树的深度为其平均查找长度(n+1)/2(和顺序查找相同)

优化

为了避免二叉搜索树退化为单支树的情况,可以自平衡成为AVL树或红黑树,使查找树的高度为O(logn)

转载请注明原文地址: https://www.6miu.com/read-96114.html

最新回复(0)