Binary Search Tree
Node *insert / delete (Node *root, int key)
通过返回 Node * 来insert和delete。注意都要 root = insert / delete (root, key),否则bst为空insert第一个元素,或者删除掉最后一个元素的时候,root指针指向的位置会出现问题。
时间复杂度都是 O(h),h为二叉树的高度。
struct Node{ int val; Node *left, *right; Node(int v):val(v),left(NULL),right(NULL){} }; class BST{ private: Node *root; Node *insert(Node *root, int key){ if (root==NULL) return new Node(key); // do not allow duplicates if (key < root->val) root->left = insert(root->left,key); else if (key > root->val) root->right = insert(root->right, key); return root; }; bool search(Node *root, int key){ if (root==NULL) return false; if (key<root->val) return search(root->left,key); else if (key>root->val) return search(root->right,key); return true; } Node *deleteNode(Node *root, int key){ if (root==NULL) return NULL; if (key<root->val) root->left = deleteNode(root->left,key); else if (key>root->val) root->right = deleteNode(root->right,key); else{ // key==root->val if (root->left==NULL && root->right==NULL){ // delete this leaf node delete root; return NULL; }else if (root->left==NULL || root->right==NULL){ Node *new_root=root->left?root->left:root->right; root->left = root->right = NULL; delete root; return new_root; }else{ // find inorder successor Node *p=root->right; while (p->left) p=p->left; root->val = p->val; root->right = deleteNode(root->right,p->val); } } return root; } void inOrder(Node *root){ if (root==NULL) return; inOrder(root->left); cout << root->val << ' '; inOrder(root->right); } public: BST():root(NULL){} void insert(int key){root=insert(root,key);} bool search(int key){return search(root,key);} void deleteNode(int key){root=deleteNode(root,key);} void inOrder(){inOrder(root);} }; int main() { BST bst; bst.insert(50); bst.insert(30); bst.insert(20); bst.insert(40); bst.insert(70); bst.insert(60); bst.insert(80); cout<<bst.search(28)<<endl; cout<<bst.search(20)<<endl; bst.inOrder(); cout<<endl; bst.deleteNode(20); bst.inOrder(); cout<<endl; bst.deleteNode(30); bst.inOrder(); cout<<endl; bst.deleteNode(50); bst.inOrder(); cout<<endl; return 0; }
void insert / delete (Node *&root, int key)
对指针的引用,效率比上述方法高。以下代码是之前数据结构课本代码:
#include <iostream> using namespace std; template <class Type> class BinarySearchTree{ private: struct node{ node *left, *right; //结点的左、右儿子的地址 Type data; //结点的数据信息 node(const Type &x, node *L=NULL, node *R=NULL):data(x),left(L),right(R){} ~node(){} }; node *root; //二叉树的根结点 bool find(const Type &x, node *t) const; void insert(const Type &x, node *&t); void remove(const Type &x, node *&t); void clear(node *&t); public: BinarySearchTree(node *t=NULL){root=t;} ~BinarySearchTree(){clear(root);} bool search(const Type &x) const; //非递归 bool find(const Type &x) const{return find(x,root);} void insert(const Type &x){insert(x,root);} void remove(const Type &x){remove(x,root);} }; template <class Type> bool BinarySearchTree<Type>::search(const Type &x) const{ node *t=root; while(t!=NULL){ if(x==t->data) return true; else if(x>t->data) t=t->right; else t=t->left; } return false; } template <class Type> bool BinarySearchTree<Type>::find(const Type &x, node *t) const{ if(t==NULL) return false; if(x<t->data) return find(x,t->left); else if(x>t->data) return find(x,t->right); else return true; } template <class Type> void BinarySearchTree<Type>::insert(const Type &x, node *&t){ if(t==NULL) t=new node(x); else if(x<t->data) insert(x,t->left); else insert(x,t->right); } template <class Type> void BinarySearchTree<Type>::remove(const Type &x, node *&t){ if(t==NULL) return; if(x<t->data) remove(x,t->left); else if(x>t->data) remove(x,t->right); else{ //找到了 删除 if((t->left==NULL)&&(t->right==NULL)){ //是叶子节点 直接删除 delete t; t = NULL; }else if((t->left!=NULL)&&(t->right!=NULL)){ //有两个儿子 node *tmp=t->left; while(tmp->right) tmp=tmp->right; t->data = tmp->data; remove(tmp->data, t->left); //直接删tmp会有问题 tmp是通过while得到的 不是通过递归得到的 删除以后无法链接 }else{ //只有一个儿子 (其实叶子结点的情况也可以并进来) node *tmp=t; t = (t->left!=NULL)?t->left:t->right; delete tmp; } } } template<class elemType> void BinarySearchTree<elemType>::clear(node *&t){ if (t!=NULL){ clear(t->left); clear(t->right); delete t; } t = NULL; } int main(){ int a[]={10,8,6,21,87,56,4,0,11,3,22,7,5,34,1,2,9}; BinarySearchTree<int> tree; for(int i=0;i<17;++i) tree.insert(a[i]); cout << tree.find(2) << endl; tree.remove(2); cout << tree.find(56) << endl; return 0; }
Reference
https://www.geeksforgeeks.org/binary-search-tree-set-1-search-and-insertion/
https://www.geeksforgeeks.org/binary-search-tree-set-2-delete/
https://www.gormanalysis.com/blog/making-a-binary-search-tree-in-cpp/

浙公网安备 33010602011771号