在二叉查找树进行基本操作的时间与树的高度成正比。
二叉查找树基本性质:
设x为树中某个结点。如果y是x的左子树中的一个结点,则key[y] <= key[x]。如果y是x的右子树中的一个结点,则key[x] <= key[y]。也就是说,某个结点x的左子树中的结点元素必定不大于其右子树中的结点元素。
二叉查找树基本操作:
1.在二叉查找树中查找某个给定的key,有递归和非递归的版本。
递归:根据二叉查找树的性质,在某个结点左子树或右子树中递归查找,直到找到叶子结点
迭代:从根结点开始迭代,根据二叉查找树性质,在左子树或右子树中查找,直到叶子结点
2.获得树中最小元素,根据二叉查找树性质,最小元素一定在整个树的最左边。
3.获得树种最大元素,根据二叉查找树性质,最大元素一定在整个树的最右边。
4.前驱和后继,有时候要给出某个结点在中序遍历树时候的前驱或后继。
后继:某一结点x的后继即具有大于key[x]的关键字中最小的那个。如果结点x右子树不为空,则结点x的后继为其右子树中最小元素。如果结点x右子树为空,假设其后继为y,则y是x的最低祖先结点,且y的左儿子也是x的祖先。
前驱:根据上述后继的分析可以得到前驱相关性质。
5.插入,与查找关键字key时过程相仿,将key插入到合适位置,但要注意当树为空时候的插入情况。
6删除。与插入相比较为复杂,分为3种情况,假设要删除结点为x
(1)当x左右孩子均为空的时候,也就是结点x为叶结点的时候,直接删除x
(2)当x左右孩子中仅有一个为空的时候,设这个结点为y,则将y设为x父结点的孩子,然后将x删除。
(3)当x左右孩子都不为空的时候,找到x的后继y,再用y替换x的内容,y孩子结点z设为其父节点的孩子,并将y删除。
具体二叉查找树代码:
#ifndef BINARY_SEARCH_TREE_H #define BINARY_SEARCH_TREE_H #include <iostream> template<typename T> struct Node { T key; Node *P; Node *L; Node *R; Node(T data = T(),Node<T> *P = NULL,Node<T> *L = NULL,Node<T> *R = NULL) { this->key = data; this->P = P; this->L = L; this->R = R; } }; template<typename T> class Binary_Search_Tree { public: Binary_Search_Tree(); ~Binary_Search_Tree(); typedef Node<T> Tree_Node; Tree_Node* Insert(const T& data); Tree_Node* Find(const T& data); void Delete(const T& data); Tree_Node* FindMax(); Tree_Node* FindMin(); void Display(); private: void free_node(Tree_Node *p); Tree_Node* tree_search(Tree_Node *x,const T& data); Tree_Node* iterative_tree_search(Tree_Node *x,const T& data); Tree_Node* tree_minimum(Tree_Node *root); Tree_Node* tree_maximum(Tree_Node *root); Tree_Node* tree_successor(Tree_Node *x); Tree_Node* tree_predecessor(Tree_Node *x); Tree_Node* tree_delete(Tree_Node *p); Tree_Node* tree_insert(Tree_Node *p); void Display(const Tree_Node *p); Tree_Node* m_pRoot; #ifdef _DEBUG int cnt; #endif }; template<typename T> Binary_Search_Tree<T>::Binary_Search_Tree() : m_pRoot(NULL) { #ifdef _DEBUG cnt = 0; #endif } template<typename T> Binary_Search_Tree<T>::~Binary_Search_Tree() { free_node(m_pRoot); #ifdef _DEBUG std::cout << "after new and free endtime the cnt is" << cnt << std::endl; #endif } template<typename T> void Binary_Search_Tree<T>::Display() { Display(m_pRoot); } template<typename T> void Binary_Search_Tree<T>::Display(const Tree_Node* p) { if(p == NULL) return ; Display(p->L); std::cout << "Node = " << p->key << std::endl; Display(p->R); } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::Insert(const T& data) { Tree_Node *z = new Tree_Node(data); #ifdef _DEBUG ++cnt; #endif return tree_insert(z); } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::Find(const T& data) { return iterative_tree_search(m_pRoot,data); } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::FindMax() { return tree_maximum(m_pRoot); } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::FindMin() { return tree_minimum(m_pRoot); } template<typename T> void Binary_Search_Tree<T>::Delete(const T& data) { Tree_Node *p = Find(data); tree_delete(p); } template<typename T> void Binary_Search_Tree<T>::free_node(Tree_Node *p) { if(p == NULL) return ; free_node(p->L); free_node(p->R); p->L = NULL; p->R = NULL; p->P = NULL; delete p; p = NULL; #ifdef _DEBUG --cnt; #endif } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::tree_search(Binary_Search_Tree<T>::Tree_Node *x,const T& data) { if(x == NULL || x->key == data) { return x; } if(data < x->key) { return tree_search(x->L,data); } else { return tree_search(x->R,data); } } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::iterative_tree_search(Binary_Search_Tree<T>::Tree_Node *x,const T& data) { while(x && x->key != data) { if(data < x->key) { x = x->L; } else { x = x->R; } } return x; } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::tree_minimum(Binary_Search_Tree<T>::Tree_Node *root) { while(root && root->L) { root = root->L; } return root; } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::tree_maximum(Binary_Search_Tree<T>::Tree_Node *root) { while(root && root->R) { root = root->R; } return root; } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::tree_successor(Binary_Search_Tree<T>::Tree_Node *x) { //if right_sub_tree is not empty if(x->R) { return tree_minimum(x->R); } //if ... is empty Tree_Node *y = x->P; while(y && x == y->R) { x = y; y = y->P; } return y; } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::tree_predecessor(Binary_Search_Tree<T>::Tree_Node *x) { if(x->L) { return tree_maximum(x->L); } Tree_Node *y = x->P; while(y && x = y->L) { x = y; y = y->P; } return y; } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::tree_insert(Binary_Search_Tree<T>::Tree_Node *z) { if(m_pRoot == NULL) { m_pRoot = z; } else { Tree_Node *y = NULL; Tree_Node *x = m_pRoot; while(x) { y = x; if(z->key < x->key) { x = x->L; } else { x = x->R; } } z->P = y; if(z->key < y->key) { y->L = z; } else { y->R = z; } } return z; } template<typename T> typename Binary_Search_Tree<T>::Tree_Node* Binary_Search_Tree<T>::tree_delete(Binary_Search_Tree<T>::Tree_Node *z) { Tree_Node *y = NULL; if(!z->L || !z->R) { y = z; } else { y = tree_successor(z); } Tree_Node *x = NULL; if(y->L) { x = y->L; } else { x = y->R; } if(x) { x->P = y->P; } if(!y->P) { m_pRoot = x; } else if(y == y->P->L) { y->P->L = x; } else { y->P->R = x; } if(y != z) { z->key = y->key; } return y; } #endif
测试代码:
#include "binary_search_tree.h" int main() { Binary_Search_Tree<int> tree; std::cout << "please enter some nums to insert with 1000 ends" << std::endl; int y; while(std::cin >> y && y != 1000) { tree.Insert(y); } tree.Display(); Binary_Search_Tree<int>::Tree_Node *p = tree.FindMin(); if(p) { std::cout << "the min is " << p->key << std::endl; } p = tree.FindMax(); if(p) { std::cout << "the max is " << p->key << std::endl; } std::cout << "please eneter a num to delete" << std::endl; int x; std::cin >> x; tree.Delete(x); std::cout << "after delete" << std::endl; tree.Display(); return 0; }
结果:please enter some nums to insert with 1000 ends
3 5 6 7 10 12 13 15 16 18 20 23 1000
Node = 3
Node = 5
Node = 6
Node = 7
Node = 10
Node = 12
Node = 13
Node = 15
Node = 16
Node = 18
Node = 20
Node = 23
the min is 3
the max is 23
please eneter a num to delete
5
after delete
Node = 3
Node = 6
Node = 7
Node = 10
Node = 12
Node = 13
Node = 15
Node = 16
Node = 18
Node = 20
Node = 23