C++实现二叉搜索树基本操作(递归+非递归+应用)
2017-04-02 12:16
447 查看
基本概念不再多讲,看下面的例子
有如图的序列,用插入法建立二叉搜索树并完成相关操作:
代码:
运行结果:
有如图的序列,用插入法建立二叉搜索树并完成相关操作:
代码:
#pragma once #include <iostream> #include <assert.h> #include <string> using namespace std; //结点定义 template <class K> struct SearchBinaryTreeNode { K _key; SearchBinaryTreeNode<K>* _left; SearchBinaryTreeNode<K>* _right; SearchBinaryTreeNode(const K& key) :_key(key) ,_left(NULL) ,_right(NULL) {} }; //搜索二叉树 template <class K> class SearchBinaryTree { typedef SearchBinaryTreeNode<K> Node; public: SearchBinaryTree() :_root(NULL) {} //中序遍历 void InOrder() { _InOrder(_root); cout << endl; } //插入 bool Insert(const K& key) { //1.若为空树则建立一个结点给_root if (NULL == _root) { _root = new Node(key); return true; } //2.不为空,需要找到key的位置,parent记录上一个结点 //因为搜索二叉树的结点值唯一,所以可以唯一的确认待插入的节点位置 //cur为空时,cur即为该位置 Node* parent = _root; Node* cur = _root; while (cur) { if (cur->_key < key) { parent = cur; cur = cur->_right; } else if (cur->_key > key) { parent = cur; cur = cur->_left; } else return false; } //找到位置以后判断链接关系,当父结点的值大,则链接在父节点左侧 if (key < parent->_key) { parent->_left = new Node(key); return true; } //当父结点的值小,则链接在父节点右侧 else if (key > parent->_key) { parent->_right = new Node(key); return true; } else return false; } bool InsertR(const K& key) { return _InsertR(_root, key); } //寻找 Node* Find(const K& key) { Node* cur = _root; while (cur) { if (cur->_key > key) { cur = cur->_left; } else if (cur->_key < key) { cur = cur->_right; } else return cur; } return NULL; } //递归法寻找 Node* FindR(const K& key) { return _FindR(_root, key); } //删除一个节点 bool Remove(const K& key) { //结点分为4类:叶子,左为空,右为空,左右均不为空 //其中叶子节点可划归为左为空或者右为空去处理 //找到该结点 Node* parent = NULL; Node* cur = _root; while (cur) { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else { Node* del = cur; //1.左为空 if (NULL == cur->_left) { if (NULL == parent) { _root = cur->_right; } else { if (parent->_left == cur) parent->_left = cur->_right; else parent->_right = cur->_right; } } //右为空 else if (NULL == cur->_right) { if (NULL == parent) { _root = cur->_left; } else { if (parent->_left == cur) parent->_left = cur->_left; else parent->_right = cur->_left; } } //左右均不为空,替换法删除 //用左子树的最右节点或者右子树的最左结点的值给待删结点 //然后删除左子树的最右节点或者右子树的最左结点 else { Node* subLeft = cur->_left; Node* subparent = cur; while (subLeft->_right) { subparent = subLeft; subLeft = subLeft->_right; } cur->_key = subLeft->_key; del = subLeft; if (subparent->_right == subLeft) subparent->_right = subLeft->_left; else subparent->_left = subLeft->_left; } delete del; cur = NULL; return true; } } return false; } //递归法删除 bool RemoveR(const K& key) { return _RemoveR(_root, key); } protected: bool _RemoveR(Node*& root, const K&key) { if (key < root->_key) _RemoveR(root->_left,key); else if (key > root->_key) _RemoveR(root->_right, key); else { Node* del = root; if (root->_left == NULL) root = root->_right; else if (root->_right == NULL) root = root->_left; delete del; return true; } return false; } Node* _FindR(Node* root, const K& key) { if (key == root->_key) return root; else if (key < root->_key) return _FindR(root->_left, key); else return _FindR(root->_right, key); } bool _InsertR(Node*& root, const K& key) { if (NULL == root) { root = new Node(key); return true; } else if (key > root->_key) { return _InsertR(root->_right, key); } else if (key < root->_key) { return _InsertR(root->_left, key); } else return false; } void _InOrder(Node* root) { if (NULL == root) { return; } _InOrder(root->_left); cout << root->_key << " "; _InOrder(root->_right); } protected: Node* _root; }; void Test() { int a[] = { 5,3,4,1,7,8,2,6,0,9 }; SearchBinaryTree<int> t; for (size_t i = 0;i < sizeof(a) / sizeof(a[0]);++i) { t.Insert(a[i]); } t.Insert(12); t.Insert(-1); t.InOrder(); SearchBinaryTreeNode<int>* ret; ret = t.Find(8); cout << "t.Find(8): " << ret->_key << endl; t.Remove(-1);t.InOrder(); t.Remove(0);t.InOrder(); t.Remove(1);t.InOrder(); t.Remove(2);t.InOrder(); t.Remove(3);t.InOrder(); t.Remove(4);t.InOrder(); t.Remove(6);t.InOrder(); t.Remove(7);t.InOrder(); t.Remove(8);t.InOrder(); t.Remove(9);t.InOrder(); t.Remove(12);t.InOrder(); t.Remove(5);t.InOrder();//这里执行之后元素全部删除,会输出一个空行 } void TestR() { int a[] = { 5,3,4,1,7,8,2,6,0,9 }; SearchBinaryTree<int> t; for (size_t i = 0;i < sizeof(a) / sizeof(a[0]);++i) { t.InsertR(a[i]); } t.InsertR(12); t.InsertR(-1); t.InOrder(); SearchBinaryTreeNode<int>* ret; ret = t.FindR(8); cout << "t.FindR(8): " << ret->_key << endl; t.RemoveR(-1);t.InOrder(); t.RemoveR(0);t.InOrder(); t.RemoveR(1);t.InOrder(); t.RemoveR(2);t.InOrder(); t.RemoveR(3);t.InOrder(); t.RemoveR(4);t.InOrder(); t.RemoveR(5);t.InOrder(); t.RemoveR(6);t.InOrder(); t.RemoveR(7);t.InOrder(); t.RemoveR(8);t.InOrder(); t.RemoveR(9);t.InOrder(); t.RemoveR(12);t.InOrder();//输出空行 } //搜索二叉树的应用:字典实现的基本原理 //key表示主键,value表示其附带信息(即所要查找的内容) template <class K,class V> struct BSTreeNode { K _key; V _value; BSTreeNode<K, V>* _left; BSTreeNode<K, V>* _right; BSTreeNode(const K& key = K(), const V& value = V()) :_key(key) ,_value(value) ,_left(NULL) ,_right(NULL) {} }; template <class K,class V> class BSTree { typedef BSTreeNode<K, V> Node; public: BSTree() :_root(NULL) {} bool Insert(const K& key, const V& value) { return _Insert(_root, key, value); } const Node* Find(const K& key) { Node* cur = _root; while (cur) { if (key < cur->_key) cur = cur->_left; else if (key > cur->_key) cur = cur->_right; else return cur; } return false; } protected: bool _Insert(Node*& root, const K& key, const V& value) { if (NULL == root) { root = new Node(key, value); return true; } else if (key < root->_key) { return _Insert(root->_left, key, value); } else if (key > root->_key) { return _Insert(root->_right, key, value); } else return false; } protected: Node* _root; }; void TestKV() { BSTree<string, string> t; t.Insert("string", "字符串"); t.Insert("some", "某些"); t.Insert("next", "下一个"); const BSTreeNode<string, string>* ret = t.Find("next"); cout << ret->_value << endl;//显然结果应该是:下一个 }
运行结果:
相关文章推荐
- c++模板类递归实现二叉搜索树及其基本操作
- C++实现二叉树的基本操作(递归+非递归)
- c++模板实现二叉树,线索化,线索化遍历,非递归遍历及一些基本操作
- 数据结构顺序栈和链栈基本操作----c++实现
- C++实现shapefile文件的读写和基本功能的操作
- 【数据结构】双向循环线性表的基本操作--C++/C实现
- c++学习笔记—单链表基本操作的实现
- C++实现有向权图的基本操作,界面友好,操作方便,运行流畅
- [C++]数据结构:有序链表SortedChain的基本实现与操作
- 栈的基本操作实现-c/c++
- 【数据结构】双向循环线性表的基本操作--C++/C实现
- 二叉树的建立(非递归建立与定义建立)与基本操作(广度和深度遍历,求叶子树高)实现
- c++学习笔记—单链表基本操作的实现
- C++实现二叉搜索树的常用操作
- C++实现有向权图的基本操作,界面友好,操作方便,运行流畅
- 详细的单链表基本操作C/C++实现
- 树的基本操作的非递归实现
- 循环双链表基本操作C++实现
- 二叉搜索树的基本操作(C代码实现)
- C++实现树的基本操作,界面友好,操作方便,运行流畅,运用模板