二叉搜索树的基本操作【结合LeetCode 例题】

    科技2022-07-21  91

    目录

    插入节点(也可以看做建树的过程)

    中序遍历

    查找

    查找最大值、最小值

    删除

    全部代码:


    插入节点(也可以看做建树的过程)

    递归的插入,如果当前节点大于插入的x,就往左走;反之小于就往右走; 递归出口就是走到了一个NULL,在此创建节点即可。

    //插入节点(也可以看做建树的过程) void Insert(Node* &t, int x){ if (t==NULL){ t=new Node; t->val=x; t->left=NULL; t->right=NULL; return; } if (x < t->val) Insert(t->left,x); else Insert(t->right,x); }

    中序遍历

    二叉搜索树的中序遍历是升序 ,这个性质可以用来判断一棵树是否为二叉搜索树。

    LeetCode 98题:https://leetcode-cn.com/problems/validate-binary-search-tree/

    //二叉搜索树的中序遍历是升序 void InOrder(Node* t){ if (t==NULL) return; InOrder(t->left); cout<<t->val<<" "; InOrder(t->right); }

    查找

    //查找值为x的节点,若x存在,返回节点指针,不存在返回NULL。 Node* Find(Node* t,int x){ if (t==NULL) return NULL; if (t->val==x) return t; if (t->val > x) Find(t->left,x); else Find(t->right,x); }

    查找最大值、最小值

    最大值就是有右孩子就一直往右走,直到尽头; 最小值就是有左孩子就一直往左走,直到尽头。

    //寻找以t为根的最大节点 Node* Find_Max(Node* t){ if (t==NULL) return NULL; while (t->right!=NULL) t=t->right; return t; } //寻找以t为根的最小节点 Node* Find_Min(Node* t){ if (t==NULL) return NULL; while (t->left!=NULL) t=t->left; return t; }

    删除

    普通二叉树的删除操作是没什么意义的,在二叉搜索树中作删除操作,要保证二叉搜索树的性质不能变,较为复杂。

    更详细的解释:删除二叉搜索树中的节点【LeetCode 450】(两种方法的实现与比较)

    //删除root中的key元素,返回根 Node* DeleteNode(Node* root, int key) { if (root==NULL) return NULL; //查找的递归出口,找不到,不做操作 if (root->val==key){ //找到了要删除 if (root->left==NULL) return root->right; //情况一 else if (root->right==NULL) return root->left; //情况二 else { //情况三:方法二 Node* t=Find_Min(root->right);//右子树的最小节点 root->val=t->val; //用最小值代替删除的节点(相当于删除了) root->right=DeleteNode(root->right,root->val); //递归的去删除右子树的替代节点 } } if (root->val > key) root->left=DeleteNode(root->left, key); //往左找 if (root->val < key) root->right=DeleteNode(root->right, key); //往右找 return root; //返回根 }

    全部代码:

    #include<iostream> using namespace std; struct Node{ int val; Node* left; Node* right; }; //插入节点(也可以看做建树的过程) void Insert(Node* &t, int x){ if (t==NULL){ t=new Node; t->val=x; t->left=NULL; t->right=NULL; return; } if (x < t->val) Insert(t->left,x); else Insert(t->right,x); } //二叉搜索树的中序遍历是升序 void InOrder(Node* t){ if (t==NULL) return; InOrder(t->left); cout<<t->val<<" "; InOrder(t->right); } //查找值为x的节点,若x存在,返回节点指针,不存在返回NULL。 Node* Find(Node* t,int x){ if (t==NULL) return NULL; if (t->val==x) return t; if (t->val > x) Find(t->left,x); else Find(t->right,x); } //寻找以t为根的最大节点 Node* Find_Max(Node* t){ if (t==NULL) return NULL; while (t->right!=NULL) t=t->right; return t; } //寻找以t为根的最小节点 Node* Find_Min(Node* t){ if (t==NULL) return NULL; while (t->left!=NULL) t=t->left; return t; } //删除root中的key元素,返回根 Node* DeleteNode(Node* root, int key) { if (root==NULL) return NULL; //查找的递归出口,找不到,不做操作 if (root->val==key){ //找到了要删除 if (root->left==NULL) return root->right; //情况一 else if (root->right==NULL) return root->left; //情况二 else { //情况三:方法二 Node* t=Find_Min(root->right);//右子树的最小节点 root->val=t->val; //用最小值代替删除的节点(相当于删除了) root->right=DeleteNode(root->right,root->val); //递归的去删除右子树的替代节点 } } if (root->val > key) root->left=DeleteNode(root->left, key); //往左找 if (root->val < key) root->right=DeleteNode(root->right, key); //往右找 return root; //返回根 } int main(){ Node* root=NULL; int a[]={0,5,8,7,4,6,2,3,9,1,11,10}; for (int i=1; i<=11; i++) Insert(root,a[i]); InOrder(root); cout<<endl; Node *p=Find(root,8); if (p==NULL) cout<<"not find"<<endl; else cout<<p->val<<endl; Node* s=Find_Max(p); cout<<s->val<<endl; s=Find_Min(p); cout<<s->val<<endl; DeleteNode(root,6); //删除 p=Find(root,8); if (p==NULL) cout<<"not find"<<endl; else cout<<p->val<<endl; s=Find_Max(p); cout<<s->val<<endl; s=Find_Min(p); cout<<s->val<<endl; }

     

    Processed: 0.009, SQL: 8