c++实现搜索二叉树
Posted MicroDeLe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++实现搜索二叉树相关的知识,希望对你有一定的参考价值。
第一次接触树,各种递归搞得眼花,总算是按书上的代码,敲了下来,记录一下
/** * Created by admin on 2021/10/27. * 搜索二叉树实现 */ #ifndef HELLOWORLD_BINARY_SEARCH_TREE_H #define HELLOWORLD_BINARY_SEARCH_TREE_H #include <istream> template <typename Object> class BinarySearchTree{ struct TreeNode{ Object object; // 数据 TreeNode *left; // 左子树指针 TreeNode *right; // 右子树指针 }; // 二进制树 TreeNode *root; // 根节点 void insert(const Object &, TreeNode *&); // 插入元素 void printTree(TreeNode *&); // 打印树 bool contain(const Object&, TreeNode *&); // 查找树中是否有该元素 TreeNode *findMax(TreeNode *&); // 找最大值 TreeNode *findMin(TreeNode *&); // 找最小值 void remove(const Object &object, TreeNode *&); void makeEmpty(TreeNode *&); TreeNode *clone(TreeNode *); public: BinarySearchTree(): root(nullptr){}; // 普通构造函数 ~BinarySearchTree(){ makeEmpty(root);} // 析构函数 BinarySearchTree(const BinarySearchTree &rhs): root(nullptr){root = clone(rhs.root);} void insert(const Object &object){ insert(object, root);} // 插入数据 void printTree(){ printTree(root);}; // 打印树 bool contain(const Object &object){ return contain(object, root);} const Object &findMax(){return findMax(root)->object;} // 找最大值 const Object &findMin(){return findMin(root)->object;} // 找最小值 void remove(const Object &object){remove(object, root);} // 删除元素 }; template<typename Object> void BinarySearchTree<Object>::insert(const Object &object, TreeNode *&treeNode) { if (treeNode == nullptr) treeNode = new TreeNode{object, nullptr, nullptr}; // 新建节点 else if (object < treeNode->object) insert(object, treeNode->left); // 向左递归插入 else if (object > treeNode->object) insert(object, treeNode->right); // 向左递归插入 } template<typename Object> void BinarySearchTree<Object>::printTree(BinarySearchTree::TreeNode *&treeNode) { if (treeNode == nullptr) return; std::cout << treeNode->object; // 前序打印 if (treeNode->left != nullptr) printTree(treeNode->left); if (treeNode->right != nullptr) printTree(treeNode->right); } template<typename Object> bool BinarySearchTree<Object>::contain(const Object &object, BinarySearchTree::TreeNode *&treeNode) { if (treeNode == nullptr) return false; else if (object < treeNode->object) contain(object, treeNode->left); else if (object > treeNode->object) contain(object, treeNode->right); else return true; // 匹配 } template<typename Object> typename BinarySearchTree<Object>::TreeNode *BinarySearchTree<Object>::findMax(BinarySearchTree::TreeNode *&treeNode) { if (treeNode == nullptr) return nullptr; if (treeNode->right == nullptr) return treeNode; return findMax(treeNode->right); } template<typename Object> typename BinarySearchTree<Object>::TreeNode *BinarySearchTree<Object>::findMin(BinarySearchTree::TreeNode *&treeNode) { if (treeNode == nullptr) return nullptr; if (treeNode->left == nullptr) return treeNode; return findMin(treeNode->left); } template<typename Object> void BinarySearchTree<Object>::remove(const Object &object, BinarySearchTree::TreeNode *&treeNode) { if (treeNode == nullptr) return; else if (object < treeNode->object) remove(object, treeNode->left); else if (object > treeNode->object) remove(object, treeNode->right); else if (treeNode->left != nullptr && treeNode->right != nullptr){ // 双节点的情况 treeNode->object = findMin(treeNode->right)->object; // 值用右树最小值替换 remove(treeNode->object, treeNode->right); // 找到替换的节点 }else{ TreeNode *oldTreeNode = treeNode; treeNode = treeNode->left != nullptr? treeNode->left: treeNode->right; delete oldTreeNode; } } template<typename Object> void BinarySearchTree<Object>::makeEmpty(BinarySearchTree::TreeNode *&treeNode) { if (treeNode == nullptr) return; makeEmpty(treeNode->left); makeEmpty(treeNode->right); delete treeNode; treeNode = nullptr; } template<typename Object> typename BinarySearchTree<Object>::TreeNode *BinarySearchTree<Object>::clone(BinarySearchTree::TreeNode *treeNode) { if (treeNode == nullptr) return nullptr; else return new TreeNode{treeNode->object, clone(treeNode->left), clone(treeNode->right)}; } #endif //HELLOWORLD_BINARY_SEARCH_TREE_H
C++实现搜索二叉树
二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
任意节点的左、右子树也分别为二叉查找树;
没有键值相等的节点。
#pragma once template<class K, class V> struct BSTreeNode { K _key; V _value; BSTreeNode<K, V>* _left; BSTreeNode<K, V>* _right; BSTreeNode(const K& key, const V& value) :_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) { if (NULL == _root)//若为空树 { _root = new Node(key, value); return true; } Node* parent = NULL; Node* cur = _root; //确定插入节点的位置 while (cur) { if (key < cur->_key) { parent = cur; cur = cur->_left; } else if (key > cur->_key) { parent = cur; cur = cur->_right; } else//已经存在key { return false; } } //插入节点 if (key > parent->_key) parent->_right = new Node(key, value); else parent->_left = new Node(key, value); } //Insert递归写法 bool InsertR(const K& key, const V& value) { return _InsertR(_root, key, value); } bool _InsertR(Node*& root, const K& key, const V& value) { if (NULL == root) { root = new Node(key, value); return true; } if (key > root->_key) return _InsertR(root->_right, key, value); else if (key < root->_key) return _InsertR(root->_left, key, value); else return false; } Node* Find(const K& key) { Node* cur = _root; while (cur) { if (key > cur->_key) cur = cur->_right; else if (key < cur->_key) cur = cur->_left; else return cur; } return NULL; } //Find递归写法 Node* FindR(const K& key) { return _FindR(_root, key); } Node* _FindR(Node* root, const K& key) { if (NULL == root) return NULL; if (key > root->_key) return _FindR(root->_right, key); else if (key < root->_key) return _FindR(root->_left, key); else return root; } bool Remove(const K& key) { Node* parent = NULL; Node* cur = _root; //确定删除节点的位置 while (cur) { if (key > cur->_key) { parent = cur; cur = cur->_right; } else if (key < cur->_key) { parent = cur; cur = cur->_left; } else { break; } } if (NULL == cur)//没有该节点 { return false; } Node* del; if (NULL == cur->_left)//删除节点的左孩子为空 { del = cur; //删除的节点为根节点 if (NULL == parent) { _root = _root->_right; } else { if (cur == parent->_left) parent->_left = cur->_right; else parent->_right = cur->_right; } } else if (NULL == cur->_right)//删除节点的右孩子为空 { del = cur; if (NULL == parent) { _root = _root->_left; } else { if (cur == parent->_left) parent->_left = cur->_right; else parent->_right = cur->_left; } } else//删除节点的左右孩子都不为空,找右子树最左节点代替该节点删除 { parent = cur; Node* leftmost = cur->_right; while (leftmost->_left) { parent = leftmost; leftmost = leftmost->_left; } del = leftmost; cur->_key = leftmost->_key; cur->_value = leftmost->_value; if (leftmost == parent->_left) parent->_left = leftmost->_right; else parent->_right = leftmost->_right; } return true; } //Remove递归写法 bool RemoveR(const K& key) { return _RemoveR(_root, key); } bool _RemoveR(Node*& root, const K& key) { if (NULL == root) return false; if (key > root->_key) { return _RemoveR(root->_right, key); } else if (key < root->_key) { return _RemoveR(root->_left, key); } else { Node* del = root; if (NULL == root->_left) { root = root->_right; } else if (NULL == root->_right) { root = root->_left; } else { Node* leftmost = root->_right; while (leftmost->_left) { leftmost = leftmost->_left; } swap(root->_key, leftmost->_key); swap(root->_value, leftmost->_value); return _RemoveR(root->_right, key); } delete del; } return true; } //中序遍历递归写法 void InOrder() { _InOrder(_root); } void _InOrder(Node* root) { if (NULL == root) return; _InOrder(root->_left); cout<<root->_key<<" "; _InOrder(root->_right); } protected: Node* _root; }; void Test() { BSTree<int, int> t; int a[] = {5, 3, 4, 1, 7, 8, 2, 6, 0, 9}; for (size_t i = 0; i < sizeof(a)/sizeof(a[0]);++i) { t.InsertR(a[i], i); } cout<<t.FindR(8)->_key<<endl; cout<<t.FindR(5)->_key<<endl; cout<<t.FindR(9)->_key<<endl; t.RemoveR(8); t.RemoveR(7); t.RemoveR(9); t.RemoveR(6); t.RemoveR(5); t.RemoveR(3); t.RemoveR(1); t.RemoveR(4); t.RemoveR(0); t.RemoveR(2); t.InOrder(); }
本文出自 “zgw285763054” 博客,请务必保留此出处http://zgw285763054.blog.51cto.com/11591804/1795294
以上是关于c++实现搜索二叉树的主要内容,如果未能解决你的问题,请参考以下文章
C++进阶第十七篇——二叉搜索树(概念+二叉搜索树实现+二叉搜索树的应用+二叉树性能分析)
C++进阶:二叉树进阶二叉搜索树的操作和key模型key/value模型的实现 | 二叉搜索树的应用 | 二叉搜索树的性能分析