【数据结构】搜索二叉树
来源:互联网 发布:淘宝 门禁ic卡 编辑:程序博客网 时间:2024/06/05 05:04
手写实现搜索二叉树:
- 树的节点定义:
class TreeNode{public: TreeNode(int v) :value(v){}; TreeNode* left_son = NULL; TreeNode* right_son = NULL; TreeNode* p = NULL; //一定保存双亲的指针 int value = 0;};
- 节点插入:
bool TreeInsert(TreeNode*& pRoot,int value){ TreeNode* pNew = new TreeNode(value);//待插入的节点 TreeNode* pParent = NULL;//父节点 TreeNode* pCur = pRoot;//子节点 while (pCur != NULL) { pParent = pCur; if (pCur->value < value) { pCur = pCur->right_son; } else if (pCur->value>value) { pCur = pCur->left_son; } else { return false; } } if (pParent == NULL)//空树 { pRoot = pNew; } else if ( pParent->value<value )//插右边 { pParent->right_son = pNew; pNew->p = pParent; } else//插左边 { pParent->left_son = pNew; pNew->p = pParent; } return true;}
- 最大值,最小值函数
TreeNode* TreeMax(TreeNode* pRoot){ while (pRoot!=NULL&&pRoot->right_son!=NULL) { pRoot = pRoot->right_son; } return pRoot;}TreeNode* TreeMin(TreeNode* pRoot){ while (pRoot!=NULL&&pRoot->left_son!=NULL) { pRoot = pRoot->left_son; } return pRoot;}
- 前驱、后继函数
TreeNode* Successor(TreeNode* pRoot){ /* 寻找节点的后继节点 方法一:中序遍历,后继即 该节点输出的后一个节点 方法二:若当前节点有右孩子,则后继为右孩子子树的最小节点 若当前节点无右孩子,则后继为其最底层的祖先,条件是该结点位于此祖先的左子树 */ if (pRoot==NULL) { return pRoot; } if (pRoot->right_son != NULL)// 当前节点有右孩子 { return TreeMin(pRoot->right_son); } TreeNode* pChild = pRoot; TreeNode* pParent = pChild->p; while (pParent != NULL&&pParent->right_son == pChild)//当前节点无右孩子,寻找满足要求的最底层祖先 { pChild = pParent; pParent = pParent->p; } return pParent;}TreeNode* Processor(TreeNode* pRoot){ /* 寻找节点的前驱节点 若当前节点有左孩子,则前驱为左孩子子树的最大节点 若当前节点无左孩子,则后继为其最底层的祖先,条件是该结点位于此祖先的右子树 */ if (pRoot == NULL) { return pRoot; } if (pRoot->left_son != NULL)//有左孩子 { return TreeMax(pRoot->left_son); } TreeNode* pChild = pRoot; TreeNode* pParent = pChild->p; while (pParent != NULL&&pParent->left_son == pChild)//无左孩子,寻找满足要求的最底层祖先 { pChild = pParent; pParent = pParent->p; } return pParent;}
- 替换函数,使用一棵树接管另一棵树的双亲
bool TransPlant(TreeNode *& pRoot, TreeNode* pOld, TreeNode* pNew){ /* 使用一棵树接管另一棵树的双亲 */ if (pRoot == NULL||pOld == NULL)//旧子树为空 { return false; } //调整父节点的指针 if (pOld->p == NULL)//父节点为空:替换了根节点 { pRoot = pNew; } else { if (pOld == pOld->p->left_son) { pOld->p->left_son = pNew; } else { pOld->p->right_son = pNew; } } //调整指向父节点的指针 if (pNew != NULL)//新子树不为空 { pNew->p = pOld->p; } return true;}
- 删除节点
void TreeDelete(TreeNode*& pRoot, TreeNode* pDelete){ /* 删除指定节点 */ if (pRoot == NULL || pDelete == NULL) return; if (pDelete->left_son == NULL)//没有孩子或者只有一个孩子,直接将孩子提上来 { TransPlant(pRoot,pDelete, pDelete->right_son); } else if (pDelete->right_son == NULL) { TransPlant(pRoot,pDelete, pDelete->left_son); } else//同时有两个孩子时 { TreeNode* successor = TreeMin(pDelete->right_son);//寻找后继,后继一定没有左孩子节点 if (successor->p != pDelete)//后继不是被删除节点的右孩子节点 { TransPlant(pRoot,successor, successor->right_son);//删除后继节点 successor->right_son = pDelete->right_son;//将后继提到被删除节点右孩子位置上:接管被删除节点的右孩子 successor->right_son->p = successor; } TransPlant(pRoot,pDelete, successor);//后继接管被删节点的双亲 successor->left_son = pDelete->left_son;//后继接管被删节点的左孩子 successor->left_son->p = successor; }}
- 中序打印函数
- 测试主函数
void TreePrint(TreeNode* pRoot){ if (pRoot == NULL) { return; } TreePrint(pRoot->left_son); cout << pRoot->value << " "; TreePrint(pRoot->right_son);}int main(){ TreeNode* pRoot(NULL); TreeInsert(pRoot, 4); TreeInsert(pRoot, 1); TreeInsert(pRoot, 9); TreeInsert(pRoot, 2); TreeInsert(pRoot, 8); TreeInsert(pRoot, 3); TreeInsert(pRoot, 6); TreePrint(pRoot); cout << endl; TreeDelete(pRoot,pRoot); TreePrint(pRoot); return 0;}
阅读全文
0 0
- 数据结构二叉搜索树
- 数据结构-----二叉搜索树
- 数据结构:二叉搜索树
- 数据结构 ---- 二叉搜索树
- 数据结构-二叉搜索树
- 【数据结构】二叉搜索树
- 【数据结构】二叉搜索树
- 数据结构---------二叉搜索树
- 数据结构--‘搜索二叉树’
- 【数据结构】二叉搜索树
- 【数据结构】二叉搜索树
- 数据结构::搜索二叉树
- 【数据结构】二叉搜索树
- 数据结构-二叉搜索树
- 数据结构:二叉搜索树
- 数据结构 二叉搜索树
- 数据结构--二叉搜索树
- 数据结构 二叉搜索树
- 一些伪类:after和:before的用法
- 前段BUG
- jmeter 安装插件管理
- Auto-Encoding Variational Bayes
- Material Design你真的了解吗?
- 【数据结构】搜索二叉树
- 三大方法教你使用智能扫地机器人
- Java遍历包中所有类
- JSP中的EL表达式
- Struts2中的ModelDriven机制及其运用
- 修改线程的名字,添加线程的动作线程的动作
- 总结-HttpClient-RetryHandler重试
- PHP的几种排序算法的比较
- 启动浏览器步骤及其驱动