二叉搜索树:对于二叉树中的任意节点,左子树中所有的值都小于当前位置的值,右子树中所有的值都大于当前位置的值。
操作:
1.插入一个数值。
2.查询是否包含某个数值。
3.删除某个数值。
插入和查找是差不多的,都是比当前值(要找的值)大就往左走,否则就往右走,直到找到为止。
最复杂的操作是删除某个节点,不过可以分为3种情况来讨论:
1.需要删除的节点没有左子树,那就把右子树提上去。
2.需要删除的节点的左子树没有右子树,那就把左子树提上去。
3.其他情况,把左子树中最大的节点提到当前删除的节点的位置。
所有操作的时间复杂度都是O(log(n))。
还是比较高效的一种数据结构。
代码:
#include <iostream> #include <algorithm> #include <map> #include <vector> #include <set> #include <math.h> #include <queue> using namespace std; typedef long long ll; #define INF 2147483647 //表示节点的结构体 struct node{ int val; node *lch, *rch; }; //如果小于当前节点往左走,否则往右走,直到走到空为止,把要插入的节点放在这。 //返回值意义是更新当前子树,想象一下从最下层开始返回的情况。 node *insert(node *p,int x){ if(p == NULL){ node *q = new node; q->val = x; q->lch = q->rch = NULL; return q; }else{ if(x < p->val) p->lch = insert(p->lch, x); else p->rch = insert(p->rch, x); return p; } } //查找数值x。 //每一个节点当做一棵子树,如果当前节点不是就找它的左右子树。 bool find(node *p,int x){ if(p == NULL) return false; else if(x == p->val) return true; else if(x < p->val) return find(p->lch, x); else return find(p->rch, x); } node *remove(node *p, int x){ if(p == NULL) return NULL; //当前子树没有找到,如果一个节点的左右子树都返回NULL表明当前子树没有找到 else if(x < p->val) p->lch = remove(p->lch, x); //向左走 else if(x > p->val) p->rch = remove(p->rch, x); //向右走 //以下为找到了的情况 //左子树为空,先保存右子树,再删除当前节点,把右子树直接挂在删除节点的原先位置。 else if(p->lch == NULL){ node *q = p->rch; delete p; return q; //左子树的右子树为空,把删除节点的左子树挂在当前位置,把删除节点的右子树挂在当前位置的右边 //这样保证了搜索树的性质 }else if(p->lch->rch == NULL){ node *q = p->lch; q->rch = p->rch; delete p; return q; }else{ //找到删除节点左子树的最右边的节点,即左子树中的最大值 q->rch node *q; for(q = p->lch;q->rch->rch != NULL; q = q->rch); //把最大值节点q->rch用r保存下来,把最大值节点的左子树提上来 node *r = q->rch; q->rch = r->lch; //把最大值节点r放在了原先删除节点的位置 r->lch = p->lch; r->rch = p->rch; delete p; return r; } return p; } int main(){ return 0; }
时间: 2024-10-10 16:56:38