C++之二叉排序树(二叉搜索树)的实现(4)---《那些奇怪的算法》
来源:互联网 发布:千语是什么软件 编辑:程序博客网 时间:2024/06/02 03:43
二叉排序树的实现难点主要集中在删除、求解节点的前驱和节点的后继这三个步骤,注意,求解节点的前驱和后继部分指的是中序遍历中的节点的前驱和后继啦,
1)二叉排序树针对删除所面临的三种情况:
1)当前节点无左右子树,直接删除该节点,修改父节点的对应指针;
2)节点p有左子树(右子树),则把p的左子树(右子树)接到p的父节点上面,并删除p节点;
3)左右子树同时存在:
- 找到节点p的中序直接节点s,把节点s的数据转移到节点p,然后删除节点s,由于节点s为p的左子树中最右边的节点,因而s无右子树,删除节点s可以归类为2);
- 找到节点p的中序直接后继节点s,并把节点s的数据转移到节点p,然后删除节点s,由于节点s为p的右子树中最左边的节点,因而s无左子树,删除节点可以归类到情况2);
- 找到p的直接前驱s,将p的左子树接到父节点上面,将p的右子树接到节点s的右子树上,然后删除节点p。
算法导轮中列举出来的几种主要情况:
2)二叉搜索树中求取前驱:
1)当前节点存在左节点;
2)当前节点是父节点的左节点;
3)当前节点是父节点的右节点。
3)二叉排序树中求取后继:
1)当前节点存在右节点;
2)当前节点是父节点的左节点;
3)当前节点是父节点的右节点。
二叉排序树的构造:
这是我们所设计的实现代码:
#include <iostream>#include <string>#include <stack>using namespace std;class BSTNode{public: int key; BSTNode* left; BSTNode* right; BSTNode* parent; BSTNode(){ key = 0; left = right = parent = NULL; } BSTNode(int key, BSTNode* l=NULL, BSTNode* r=NULL, BSTNode* p=NULL) : key(key), left(l), right(r), parent(p){ }};void BSTree_insert(BSTNode* root, BSTNode *node){ BSTNode *temp=NULL; while (root != NULL){ temp = root; if (node->key < temp->key){ root = root->left; } else{ root = root->right; } } node->parent = temp; if (temp == NULL){ root = node; } else if (node->key < temp->key){ temp->left = node; } else{ temp->right = node; }}BSTNode* BSTree_Min(BSTNode* root){ BSTNode* temp=NULL; //*********** while (root != NULL){ temp=root; root = root->left; } return temp;}BSTNode* BSTree_Max(BSTNode* root){ BSTNode* temp=NULL; //*********** while (root != NULL){ temp=root; root = root->right; } return temp;}//中序遍历中求取节点的后继节点BSTNode* BSTree_suc(BSTNode* node){ if (node->right) return BSTree_Max(node->right); //如果节点没有右节点,那么现在也要考虑两种情况: //1)节点是父节点的左节点 //2)节点是父节点的右节点 BSTNode* parent = node->parent; while (node != NULL&&node == parent->right){ node = parent; parent = parent->parent; } return parent;}//中序遍历中求取节点的前驱节点BSTNode* BSTree_predecess(BSTNode* node){ //如果节点node有左节点,那么其前驱是其左节点中值最大的; if (node->left) return BSTree_Max(node->left); //如果节点node没有左节点,现在需要考虑两种情况, //1)节点是父节点的右节点; //2)节点是其父节点的左节点; BSTNode* parent = node->parent; while (parent != NULL&&node == parent->left){ node = parent; parent = parent->parent; } return parent;}void BSTree_remove_pre(BSTNode* node){ BSTNode* temp = NULL; //当前节点右子树为空 if (!node->right){ temp = node; //当前节点的父节点不为空 if (node->parent){ //当前节点是父节点的左节点 if (node->parent->left == node){ node->parent->left = node->left; } //当前节点是父节点的右边节点 else{ node->parent->right = node->left; } } else{ node = node->left; } delete temp; } else if(!node->left){ temp = node; //当前节点左子树为空,右子树不空空 if (node->parent){ //当前节点是父节点的左节点 if (node->parent->left == node){ node->parent->left = node->right; } //当前节点是父节点的右节点 else{ node->parent->right = node->right; } } else{ node = node->right; } delete temp; } else{ BSTNode* sucNode = NULL; temp = node; //采用这种方法是为了避免所有都使用其前驱替换,考虑一下删除以10为前驱的节点的时候,形成的结构是怎样的???很难吧! sucNode = node->left; while (sucNode->right){ temp = sucNode; sucNode=sucNode->right; } node->key = sucNode->key; if (temp != node){ temp->right = sucNode->left; } else{ temp->left = sucNode->left; } delete sucNode; }}void BSTree_remove_post(BSTNode* node){ BSTNode* temp = NULL; if (!node->right){ temp = node; if (node->parent){ if (node->parent->left == node){ node->parent->left = node->left; } else{ node->parent->right = node->left; } } else{ node = node->left; } delete temp; } else if (!node->left){ temp = node; if (node->parent){ if (node->parent->left == node){ node->parent->left = node->right; } else{ node->parent->right = node->right; } } else{ node = node->right; } delete temp; } else{ BSTNode* sucNode = NULL; temp = node; sucNode = node->right; while (sucNode->left){ temp = sucNode; sucNode = sucNode->left; } node->key = sucNode->key; if (temp != node){ temp->left = sucNode->right; } else{ temp->right = sucNode->right; } delete sucNode; }}void BSTree_remove_plus(BSTNode* node){ BSTNode* temp = NULL; if (!node->right){ temp = node; node = node->left; delete temp; } else if (!node->left){ temp = node; node = node->right; delete temp; } else{ BSTNode* s = NULL; temp = node; s = node->left; while (s->right){ s = s->right; } s->right = node->right; node = node->left; delete temp; }}BSTNode* BSTree_remove_Non_standard( BSTNode* node){ BSTNode* x; BSTNode* y; if ((node->left == NULL || node->right == NULL)){ y = node; } else{ y = BSTree_suc(node); } if (y->left != NULL){ x = y->left; } else{ x = y->right; } if (x != NULL){ x->parent = y->parent; } if (y->parent == NULL){ } else if (y == y->parent->left){ y->parent->left = x; } else{ y->parent->right = x; } if (y != node){ node->key = y->key; } return y;}BSTNode* BSTree_search(BSTNode* node, int val){ if (node == NULL || val == node->key){ return node; } if (val < node->key){ BSTree_search(node->left, val); } else{ BSTree_search(node->right, val); }}void preorder_show(BSTNode* root){ stack<BSTNode*> s; while (root != NULL || !s.empty()){ while (root != NULL){ cout << root->key << " "; s.push(root); root = root->left; } if (!s.empty()){ root = s.top(); s.pop(); root = root->right; } } cout << endl;}void inorder_show(BSTNode* root){ stack<BSTNode*> s; while (root != NULL||!s.empty()){ while (root != NULL){ s.push(root); root = root->left; } if (!s.empty()){ root = s.top(); cout << root->key << " "; s.pop(); root = root->right; } } cout << endl;}void postorder_show(BSTNode* root){ stack<BSTNode*> s; BSTNode* cur = NULL; BSTNode* pre = NULL; s.push(root); while (!s.empty()){ cur = s.top(); if ((cur->left == NULL&&cur->right == NULL) || (pre != NULL && (pre==cur->left||pre==cur->right))){ cout << cur->key << " "; s.pop(); pre = cur; } else{ if (cur->right != NULL){ s.push(cur->right); } if (cur->left != NULL){ s.push(cur->left); } } } cout << endl;}void preOrder(BSTNode* root){ if (root != NULL){ cout << root->key << endl; preOrder(root->left); preOrder(root->right); }}void inOrder(BSTNode* root){ if (root != NULL){ inOrder(root->left); cout << root->key << endl; inOrder(root->right); }}void postOrder(BSTNode* root){ if (root != NULL){ postOrder(root->left); postOrder(root->right); cout << root->key << endl; }}int main(){ int a[] = { 10, 15, 200, 150, 30, 6, 1000 ,8,170}; BSTNode *root=new BSTNode(10, NULL, NULL, NULL); for (int i = 1; i < 9; i++){ BSTNode* node = new BSTNode(a[i]); BSTree_insert(root, node); } cout << "我们求取节点30的前驱:" << endl; BSTNode* node = BSTree_search(root, 30); BSTNode* pre_Node_30 = BSTree_predecess(node); if (pre_Node_30){ cout <<"找到啦:"<< pre_Node_30->key << endl; } else{ cout << "对不起,没有找到30的前驱节点!!!" << endl; } cout << "我们求取节点8的后继:" << endl; node = BSTree_search(root, 8); BSTNode* post_Node_8 = BSTree_suc(node); if (post_Node_8){ cout << "找到啦:" << post_Node_8->key << endl; } else{ cout << "对不起,没有找到8的后继节点!!!" << endl; } cout << "先序遍历: "; preorder_show(root); cout << "中序遍历: "; inorder_show(root); cout << "后序遍历: "; postorder_show(root); cout << "\n"; cout << "先序遍历: "<<endl; preOrder(root); cout << "中序遍历: "<<endl; inOrder(root); cout << "后序遍历: "<<endl; postOrder(root); node = BSTree_search(root, 150); BSTree_remove_pre(node); cout << "删除节点150之后的先序遍历结果:" << endl; preorder_show(root); return 0;}
运行结果:
参考博客:
二叉树删除规则: 二叉查找树的插入和删除详解
二叉树前驱和后继规则:二叉搜索树节点的前驱后继节点
阅读全文
0 0
- C++之二叉排序树(二叉搜索树)的实现(4)---《那些奇怪的算法》
- C++实现二叉树的镜像操作(18)---《那些奇怪的算法》
- C++之平衡二叉树的判定(25)---《那些奇怪的算法》
- C++之根据组合遍历顺序生成二叉树(25)---《那些奇怪的算法》
- C++之实现大顶堆(1)---《那些奇怪的算法》
- C++之统计二叉树中路径和为定值的所有路径(24)---《那些奇怪的算法》
- 二叉搜索树(二叉查找树,二叉排序树)的详细实现
- C++之排序算法(2)---《那些奇怪的算法》
- 3.16(c程序实现)特殊的平衡二叉搜索树之完全二叉搜索树
- C++之堆的实现(5)---《那些奇怪的算法》
- C++之最长递增子序列的实现(20)---《那些奇怪的算法》
- C++之快速排序(3)---《那些奇怪的算法》
- C++之堆排序(6)---《那些奇怪的算法》
- C++之归并排序(7)---《那些奇怪的算法》
- 二叉排序树(二叉搜索树,BST)的使用
- 二叉排序树(二叉搜索树)
- 二叉排序树(二叉搜索树)
- 二叉搜索树(二叉排序树)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛Train Seats Reservation(树状数组的运用)
- 反爬虫措施
- SecureCRT如何安装MySQL,步骤
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛-- B. Train Seats Reservation-(区间更新,单点查询思想)
- jQuery学习笔记(一)_简介
- C++之二叉排序树(二叉搜索树)的实现(4)---《那些奇怪的算法》
- windows环境下Apache2.4+Tomcat8配置学习笔记
- 月老的烦恼(1)
- WXS 模块
- java.lang.NoSuchMethodException异常解决
- Java对象创建—深入理解Java虚拟机(四)
- 注解
- HBase 数据文件在HDFS上的存储
- na 斐波那契数列f(f(n))