二叉查找树或者是一棵空二叉树;或者是具有下列性质的二叉树:
(1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。(3)根结点的左右子树分别也是二叉查找树。
二叉查找树可以用来组织一组数据,并且实现在这组数据上的快速检索。
二叉查找树或者是一棵空二叉树;或者是具有下列性质的二叉树:
(1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
(3)根结点的左右子树分别也是二叉查找树。
二叉查找树可以用来组织一组数据,并且实现在这组数据上的快速检索。
向二叉查找树中插入新结点必须保证插入新结点后,二叉树仍然满足二叉查找树的定义。
如何在二叉查找树中插入新结点?
(1)若二叉查找树为空,则新结点应作为二叉查找树的根结点。
(2)将新结点的值和根结点的值比较,如果相等返回。(此时要插入的结点在树中已存在)
(3)如果新结点的值小于根结点的值,则转二叉查找树的左子树继续插入操作。
(4)如果新结点的值大于根结点的值,则转二叉查找树的右子树继续插入操作。
从二叉查找树上删除结点应保证结点删除后得到的二叉树仍然是二叉查找树。
如何从二叉查找树中删除结点?
(1)如果要删除的结点是叶子结点,直接删除并更新父结点指针。
(2)如果要删除的结点只有一棵非空子树,则令该非空子树代替被删除的结点作为被删除结点父结点的相应子树。
(3)如果要删除的结点的两棵子树均非空,问题比较复杂,此时用要删除结点的中序前趋替换要删除的结点,再运用(1)和(2)中的方法删除处在原来位置上的要删除结点的中序前趋。而前驱结点是左子树的右下角的那个结点。
下面是用C++实现的二叉搜索树?
1 template <typename Entry> 2 class binary_tree 3 { 4 protected: 5 //定义树结点,方便访问,不封装,全部开放 6 class binary_node 7 { 8 public: 9 Entry data; //数据域 10 binary_node* lchild; //指向左子树的指针域 11 binary_node* rchild; //指向右子树的指针域 12 binary_node(){} //无参数构造函数 13 binary_node(const Entry& x):data(x),rchild(null),lchild(null){} //带参数构造函数 14 }; 15 16 binary_node* root; //指向根结点的指针 17 18 public: 19 binary_tree(); 20 binary_tree(const binary_tree& bt); 21 virtual ~binary_tree(); 22 bool empty() const; 23 int size() const; 24 int height() const; 25 void clear(); 26 void preorder(binary_node*root,void(*visit)(Entry&)); 27 void inorder(binary_node*root,void(*visit)(Entry&)); 28 void postorder(binary_node*root,void(*visit)(Entry&)); 29 void level_traversal(binary_node*root,void(*visit)(Entry&)) 30 int insert(const Entry&); 31 int remove(const Entry&); 32 binary_tree& operator=(const binary_tree& bt); 33 34 }; 35 36 //二叉查找树,普通二叉树的基础上写 37 template <typename Entry> 38 class search_tree: public binary_tree 39 { 40 public: 41 int tree_search(Entry&) const; 42 int insert(const Entry&); 43 int remove(const Entry&); 44 45 }; 46 47 48 //按值查找结点 49 template <typename Entry> 50 search_tree<Entry>::binary_node<Entry>* search_for_node(binary_node* root,const Entry& target) 51 { 52 while(root->data != target && root != NULL) 53 if(root->data < target) root = root->rchild; 54 else root = root->lchild; 55 return root; 56 } 57 58 //查找,并且将找到的data放入传入变量中 59 template <typename Entry> 60 int search_tree<Entry>::tree_search(const Entry& target) const 61 { 62 int result = 1; 63 binary_node* found = search_for_node(target); 64 if(found == NULL) result = 0; 65 else target = found->data; 66 return result; 67 } 68 69 70 //查找并且插入 71 template <typename Entry> 72 int search_tree<Entry>::search_and_insert(binary_node* root,const Entry& new_data) 73 { 74 if(root == NULL) 75 { 76 root = new binary_node(new_data); 77 return 1; 78 } 79 else if(new_data < root->data) 80 return search_and_insert(root->lchild,new_data); 81 else if(new_data > root->data) 82 return search_and_insert(root->rchild,new_data); 83 else return 0; 84 } 85 86 //插入操作 87 template <typename Entry> 88 int search_tree<Entry>::insert(const Entry& new_data) 89 { 90 return search_and_insert(root,new_data); 91 } 92 93 94 //删除结点操作 95 template <typename Entry> 96 int search_tree<Entry>::remove_node(binary_node* node) 97 { 98 if(root == NULL) return 0; 99 if(node->rchild == NULL) node = node->lchild; 100 else if(node->lchild == NULL) node = node->rchild; 101 else 102 { 103 binary_node* parent = NULL; 104 binary_node* son = node->lchild; 105 /*找到要删除结点的左子树的最右下角的结点,即为待删除结点的中序前驱结点*/ 106 while(temp->rchild != NULL) 107 { 108 parent = son; 109 son = son->rchild; 110 } 111 //parent是前驱结点的父节点,待删除结点的前驱结点为子节点son。 112 node->data = son->data; //将前驱结点放到待删除结点的位置 113 if(son->lchild != NULL) //删除前驱结点 114 { 115 son->data = son->lchild->data; 116 delete son-lchild; 117 } 118 119 } 120 return 1; 121 122 } 123 124 //查找并且删除 125 template <typename Entry> 126 int search_tree <Entry>::search_and_destroy(binary_node* root,const Entry& target) 127 { 128 if(root == NULL || root->data == target) 129 return remove_node(root); 130 else if(root->data < target) 131 search_and_destroy(root->rchild,target); 132 else search_and_destroy(root->lchild,target); 133 } 134 135 136 //删除操作 137 template <typename Entry> 138 int search_tree<Entry>::remove(const Entry& target) 139 { 140 return search_and_destroy(root,target); 141 }