什么是搜索二叉树:
二叉树(binary)是一种特殊的树。二叉树的每个节点最多只能有2个子节点:由于二叉树的子节点数目确定,所以可以直接采用上图方式在内存中实现。每个节点有一个左子节点(left children)和右子节点(right children)。左子节点是左子树的根节点,右子节点是右子树的根节点。
如果我们给二叉树加一个额外的条件,就可以得到一种被称作二叉搜索树(binary search tree)的特殊二叉树。二叉搜索树要求:每个节点都不比它左子树的任意元素小,而且不比它的右子树的任意元素大。
二叉搜索树可以方便的实现搜索算法。在搜索元素x的时候,我们可以将x和根节点比较:
1. 如果x等于根节点,那么找到x,停止搜索 (终止条件)
2. 如果x小于根节点,那么搜索左子树
3. 如果x大于根节点,那么搜索右子树
二叉搜索树所需要进行的操作次数最多与树的深度相等。n个节点的二叉搜索树的深度最多为n,最少为log(n)。
下面是用C++语言实现的二叉搜索树,并有搜索,插入,删除,寻找最大最小节点的操作。
"BSTree.h"
<strong><span style="font-size:18px;">#pragma once template<class K,class V> class BSTreeNode { public: 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 (_root == NULL) { _root = new Node(key,value); } //_root != NULL Node* cur = _root; Node* parent = NULL; while (cur) { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else//cur->_key == key { return false; } } if (parent->_key > key) { parent->_left = new Node(key,value); } else { parent->_right = new Node(key,value); } } Node* Find(const K& key) { if (_root == NULL) { return NULL; } 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; } bool ReMove(const K& key) { Node* cur = _root; Node* parent = NULL; while (cur) { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else { break; } } if (cur == NULL)//树不存在或者找不到的情况下 { return false; } if (cur->_left == NULL) { //parent->_left = cur->_right; if (parent == NULL)//处理删除节点为根节点的情况 { _root = cur->_right; } else { if (parent->_left == cur) { parent->_left = cur->_right; } else //parent->_right == cur { parent->_right = cur->_right; } } } else if (cur->_right == NULL) { //parent->_right = cur->_left; if (parent == NULL)//处理删除节点为根节点的情况 { _root = cur->_left; } else { if (parent->_left == cur) { parent->_left = cur->_left; } else //parent->_right == cur { parent->_right = cur->_left; } } } else//左右孩子都有节点 { parent = cur;//这句代码刚刚忘记加了,导致程序崩溃 //要确保while循环进不去的时候,parent能有赋值 Node* tmp = cur->_right; while (tmp->_left) { parent = tmp; //找右孩子的最左节点 tmp = tmp->_left; } cur->_key = tmp->_key; cur->_value = tmp->_value; if (parent->_left == tmp) { parent->_left = tmp->_right; } else //parent->_right == tmp { parent->_right = tmp->_right; } delete tmp;//记得要释放内存 } } void InOrder() { return _InOrder(_root); } private: void _InOrder(Node*& root) { if (root == NULL) { return; } _InOrder(root->_left); cout<<root->_key<<" "; _InOrder(root->_right); } private: Node* _root; }; </span></strong>
"test.cpp"
<strong><span style="font-size:18px;">#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; #include "BSTree.h" void TestBSTree() { BSTree<int,int> bs; int arr[] = {5,9,3,6,7,0,4,2,8,1}; int size = sizeof(arr)/sizeof(arr[0]); for (int i = 0;i <size;i++) { bs.Insert(arr[i],i+1); } cout<<bs.Find(0)->_key<<endl; cout<<bs.Find(0)->_value<<endl; bs.InOrder(); cout<<endl; bs.ReMove(0); bs.ReMove(3); bs.ReMove(4); bs.ReMove(7); bs.ReMove(8); //bs.ReMove(55); bs.InOrder(); cout<<endl; } int main() { TestBSTree(); system("pause"); return 0; }</span></strong>