动态查找之-二叉排序树
2017-05-20 18:32
232 查看
二叉排序树简叙
从图上可得出二叉排序树的基本概念。
左子树小于根,右子树大于根
中序遍历后有序
树中最小的树在最左边,最大的在最右边
这里主要分析一下二叉排序树的插入和删除。
插入
pCur = new Node(key, value); if (key < pParent->_key) { pParent->_pLeft = pCur; } else if(key>pParent->_key) { pParent->_pRight = pCur; }
这里只截取插入时的代码,即因为已经找到插入位置。
我们只需创建一个新的节点,然后判断待插入的key值和当前根节点的大小,即可进行插入,二叉排序树的插入都是在空指针域出进行。
删除
整个程序应该就删除比较复杂一点,只要能将它的示意图画出来,其实就很简单了。删除的几种情况:
画图的水平略显粗糙
如果左右子树都没有的话,直接进行删除就好了,如果是只有右子树或者左子树,那就要分情况了,如下:
单独没有右子树和单独没有左子树同理。
如果左右都有的话:
下面是整个代码
#pragma once #include<iostream> #include<stdlib.h> using namespace std; template <class K,class V> struct BSTNode { BSTNode(const K& key,const V& value) : _pLeft(NULL) , _pRight(NULL) , _key(key) , _value(value) {} BSTNode<K,V>* _pLeft; BSTNode<K,V>* _pRight; K _key; V _value; }; template <class K,class V> class BSTree { typedef BSTNode<K, V> Node; public: BSTree() :_pRoot(NULL) {} bool Insert(const K& key, const V& value) { if (NULL == _pRoot) { _pRoot = new Node(key, value); return true; } Node* pCur = _pRoot; Node* pParent = NULL; while (pCur) { if (key < pCur->_key) { pParent = pCur;//更新双亲 pCur = pCur->_pLeft; } else if (key>pCur->_key) { pParent = pCur; pCur = pCur->_pRight; } else { return false; } } //找到了插入的位置,然后创建待插入的结点 pCur = new Node(key, value); if (key < pParent->_key) { pParent->_pLeft = pCur; } else if (key>pParent->_key) { pParent->_pRight = pCur; } return true; } bool Remove(const K& key) { if (NULL == _pRoot) return false; if (NULL == _pRoot->_pLeft&& NULL == _pRoot->_pRight) { delete _pRoot; _pRoot= NULL; return true; } //开始找删除的位置 Node *pCur = _pRoot; Node *pParent = NULL; while (pCur) { if (key < pCur->_key) { pParent = pCur; pCur = pCur->_pLeft; } else if (key>pCur->_key) { pParent = pCur; pCur = pCur->_pRight; } else break; } //出了循环,位置肯定找到了 if (pCur == NULL) { return false; } if (NULL == pCur->_pLeft) { if (pCur->_key == key)//判断是否为根节点 { _pRoot = pCur->_pRight; delete pCur; pCur = NULL; return true; } else if (pParent->_pLeft == pCur)//判断是否为双亲的左结点 { pParent->_pLeft = pCur->_pRight; } else//双亲的右结点 { pParent->_pRight = pCur->_pRight; } } else if (NULL == pCur->_pRight) { if (pCur->_key == key) { _pRoot = pCur->_pLeft; delete pCur; pCur = NULL; return true; } else if (pParent->_pRight = pCur) { pParent->_pRight = pCur->_pLeft; } else { pParent->_pLeft = pCur->_pLeft; } } else//到了这里,说明待删除的结点左右孩子都有 { Node* sub = pCur; Node* First = pCur->_pRight; if (First->_pLeft) { sub = First; First = First->_pLeft; } swap(pCur->_key, First->_key); swap(pCur->_value, First->_value); pCur = First; if (pCur->_pLeft == NULL) { if (sub->_pLeft == pCur) { sub->_pLeft = pCur->_pRight; } else { sub->_pRight = pCur->_pRight; } } else if (pCur->_pRight == NULL) { if (sub->_pLeft == pCur) { sub->_pLeft = pCur->_pLeft; } else { sub->_pLeft = pCur->_pLeft; } } } delete pCur; pCur = NULL; return true; } Node* Find(const K& key) { if (NULL == _pRoot) return NULL; Node *pCur = _pRoot; while (pCur) { if (key < pCur->_key) pCur = pCur->_pLeft; else if (key>pCur->_key) pCur = pCur->_pRight; else break; } return pCur; } bool Insert_R(const K& key, const V& value) { return _Insert_R(_pRoot, key, value); } bool Remove_R(const K& key) { return _Remove_R(_pRoot, key); } void MidOrder() { _MidOrder(_pRoot); cout << endl; } protected: bool _Insert_R(Node*& pRoot, const K& key, const V& value) { if (NULL == pRoot) { pRoot = new Node(key, value); return true; } if (key < pRoot->_key) return _Insert_R(pRoot->_pLeft, key, value); else if (key>pRoot->_key) return _Insert_R(pRoot->_pRight, key, value); else return false; } bool _Remove_R(Node *&pRoot, const K&key) { if (NULL == pRoot) return false; if (key > pRoot->_pLeft) return _Remove_R(pRoot->_pRight, key); else if (key < pRoot->_key) return _Remove_R(pRoot->_pLeft, key); else { Node *pCur = pRoot; if (pRoot->_pLeft == NULL) pRoot = pRoot->_pRight; else if (pRoot->_pRight == NULL) pRoot = pRoot->_pLeft; else { Node *First = pRoot->_pRight; while (First->_pLeft) { First = First->_pLeft; } swap(pCur->_key, First->_key); swap(pCur->_value, First->_value); return _Remove_R(pRoot->_pRight, key); } delete pCur; pCur = NULL; return true; } } void _MidOrder(Node* _pRoot) { if (NULL == _pRoot) return; _MidOrder(_pRoot->_pLeft); cout << _pRoot->_key << " "; _MidOrder(_pRoot->_pRight); } protected: BSTNode<K, V>* _pRoot; };
最后是测试代码:
#include"5_15SortBinaryTree.h" int main() { int a[10] = { 5, 3, 1, 4, 0, 2, 7, 6, 8, 9 }; BSTree<int, int> s; for (int idx = 0; idx < 10; idx++) { s.Insert_R(a[idx], idx); } s.MidOrder(); s.Remove(5); s.MidOrder(); return 0; }
相关文章推荐
- 数据结构编程笔记二十五:第九章 查找 二叉排序树(动态查找表)查找算法的实现
- 动态查找表之二叉排序树
- 12.动态查找.二叉排序树
- 动态查找—二叉排序树
- 动态查找之二叉排序树(BST)
- 初学数据结构---动态查找之二叉排序树
- Java实现动态表查找--二叉排序树
- 动态查找之二叉排序树,C++代码实现
- 查找(二)动态查找:二叉排序树的插入与输出操作
- 动态查找之二叉排序树
- 动态查找——二叉排序树
- 数据结构(22)--动态查找之二叉排序树(二叉查找树)
- 【查找--动态查找表】简单的二叉查找树(又称二叉排序树)
- 【数据结构与算法】动态查找--二叉排序树
- 动态查找表之二叉排序树
- 数据结构_查找_动态查找表_二叉排序树
- 动态查找表之二叉排序树的查找、遍历、删除
- 数据结构实验之查找一:二叉排序树
- 二叉排序树的操作(建立、插入、删除和查找)
- 【判断两棵二叉排序树是否相同】数据结构实验之查找一:二叉排序树