讲解引用:http://lib.csdn.net/article/datastructure/9204
BSTree.h
#ifndef _BSTREE_ #define _BSTREE_ #define debug(); cout<<__LINE__<<endl; #include <iostream> using namespace std; template<typename T> class BSTree { private: struct Node { T date ; Node* _left; Node* _right; Node(T x, Node* y, Node* z):date(x), _left(y), _right(z){ } }; Node *_root ; public: BSTree(); bool search(const T& value); bool del(const T& value, Node*& temp); void erase(const T& value); bool insert(const T& value); void inorder_travel(const Node* temp); void print(); }; template<typename T> BSTree<T>::BSTree() { _root = nullptr;//注意这里一定不要写的太麻烦了, }//关于Node类型的指针到底是作为什么来使用,再讨论 template<typename T> bool BSTree<T>::search(const T& value)//这里不能返回实际下标,为了保持封装特性,只返回有没有这个元素 { Node* temp = _root; while( temp ) { if( value < temp->date ) temp = temp->_left; else if( value > temp->date ) temp = temp->_right; else return true; } return false; } template<typename T> bool BSTree<T>::insert(const T& value) { if( !_root ) { _root = new Node(value, nullptr, nullptr); return true; } Node* pos = _root; Node* father = nullptr; while( pos ) { if(value < pos->date) father = pos, pos = pos->_left;//pos总是走在前面去试探,是否退出循环 else if(value > pos->date) father = pos, pos = pos->_right; else return false; } //找到插入位置之后,判断插入在父节点的左边还是右边 if(value < father->date) father->_left = new Node(value, nullptr, nullptr); if(value > father->date) father->_right = new Node(value, nullptr, nullptr); return true; } template<typename T> void BSTree<T>::inorder_travel(const Node* temp) { if( temp ) { inorder_travel(temp->_left); cout << temp -> date << ' '; inorder_travel(temp->_right); } } template<typename T> void BSTree<T>::print( ) { inorder_travel(_root); cout << endl; } template<typename T> bool BSTree<T>::del(const T& value, Node*& temp) { if(!temp) return false; if( temp->date == value) { if(temp->_left == nullptr)//要删除的节点只有左子树 { Node* s = temp; temp = temp->_right; free(s); } else if (temp->_right == nullptr)//要删除的节点只有右子树 { Node* s = temp; temp = temp->_left; free(s); } else { Node* dell_pre = temp; Node* dell = temp->_right; while(dell->_left) dell_pre=dell, dell=dell->_left; //dell_pre将指向要删除的前一个节点 //dell将指向要除的节点 temp->date = dell->date; dell_pre->_left = nullptr; free(dell); } return true; } else if( value < temp->date) del(value, temp->_left); else del(value, temp->_right); return false; } template<typename T> void BSTree<T>::erase(const T& value) { del(value, _root ); } #endif
BSTree.cpp
#include <iostream> #define debug(); cout<<__LINE__<<endl; #include "BSTree.h" using namespace std; int main() { BSTree<int> a; int test[] = {3, 2, 7, 4, -999, 0, 18 }; for(auto r : test) a.insert(r); cout << a.search(7) << endl; a.print(); a.erase(-999); a.print(); }