二叉搜索树 与 平衡二叉树

定义:BST (Binary Seach Tree) 二叉搜索树 也称二叉排序树

      二叉搜索树或者是一棵空树、或者是一棵具有下列特性的非空二叉树

    1、若左子树非空 ,则左子树上所有结点关键字值均小于根节点的关键字值。

    2、若右子树非空 ,则右子树上所有结点关键字值均大于根节点的关键字值。

    3、左右子树本身也分别是一棵二叉搜索树

 1 class Solution {
 2 public:
 3     TreeNode* insertIntoBST(TreeNode* root, int val) {
 4         if(!root) return root;
 5         TreeNode* p=root,*pre=NULL;
 6         while(p)
 7         {
 8             pre=p;
 9             if(p->val>val)
10                 p=p->left;
11             else if(p->val<val)
12                 p=p->right;
13             else return root;//当前节点的值等于val 不需要在插入
14         }
15         //找到要插入的节点的前一个节点pre
16         TreeNode *node=new TreeNode(val);
17         if(pre->val>val) pre->left=node;
18         else pre->right=node;
19         return root;
20     }
21 };

二叉树搜索树的删除算法

 1  //二叉搜索树的删除分为三种情况
 2  /*
 3  ** p为需要删除的结点
 4  ** 1、若p是叶子节点直接删除p
 5  ** 2、若p只有一棵左子树或右子树 让p的子树成为p父结点的子树 替代p的位置 删除p
 6  ** 3、若p有左右两棵子树 有两种做法
 7  **    a、用p的左子树替代p父节点的左子树,p的右子树插入到中序遍历p的前驱结点的右子树 删除p
 8  **    b、把p的中根序遍历的前驱p_pre(或后继)的值赋给p 并删除p_pre 删除时要考虑p_pre的左子树
 9  */
10 class Solution {
11 public:
12     TreeNode* deleteNode(TreeNode* root, int key) {
13         TreeNode *p=root,*p_root=NULL;//p值为key的节点 p_root代表p的根节点
14         while(p&&p->val!=key)//查找值为key的节点p
15         {
16             p_root=p;
17             if(key<p->val)p=p->left;
18             else p=p->right;
19         }
20         if(!p) return root;//未找到节点值为key的节点 返回root
21 
22         //判断节点p是否是根节点 /节点p在 p_root的左边还是右边
23         int flag=0;//0代表 p是根节点;-1 代表p是p_root的左子树; 1代表p是p_root的右子树
24         if(p==root) flag=0;
25         else if(p->val<p_root->val)flag=-1;
26         else flag=1;
27 
28         TreeNode * after_delete_p;//删除p后剩下结点的头结点
29         //情况1,2的结合
30         if(!p->right)//p的右子树不存在
31         {
32             after_delete_p=p->left;
33             delete(p);
34         }
35         else if(!p->left)//p的左子树不存在
36         {
37             after_delete_p=p->right;
38             delete(p);
39         }
40         //情况3 p的左右子树都存在 使用p的直接前驱替换p 并删除p的直接前驱
41         else
42         {
43             TreeNode*p_pre=p->left,*p_pre_root=p;//分别代表p的直接前驱 和p的直接前驱的根节点
44             while(p_pre->right)//找到p的直接前驱
45             {   
46                 p_pre_root=p_pre;
47                 p_pre=p_pre->right;
48             }
49             p->val=p_pre->val;//将p的值令为p的直接前驱的值
50             if(p_pre_root==p) //如果p的直接前驱就是p的左孩子的话
51                 p_pre_root->left=p_pre->left;//p的左孩子等于p的直接前驱的左孩子
52             else 
53                 p_pre_root->right=p_pre->left;//p的直接前驱的根节点的右孩子 等于p的直接前驱的左孩子
54             after_delete_p=p;
55             delete(p_pre);//删除p的直接前驱
56         }
57         if(flag==0) return after_delete_p;//若p是根节点
58         else if(flag==-1) //若p在p_root 左边
59         {
60             p_root->left=after_delete_p;
61             return root;
62         }
63         else //在 p_root 右边
64         {
65             p_root->right=after_delete_p;
66             return root;
67         }
68     }
69 };
 1 //伪代码版
 2 bool DeleteBST(TreeNode& root,int key)
 3 {
 4     if(!root) return false;
 5     else
 6     {
 7         if(root->val==key) return Delete(root);
 8         else if(key<root->val) return DeleteBST(root->left);
 9         else return return DeleteBST(root->right);
10     }
11 }
12 bool Delete(TreeNode &p)
13 {
14     if(!p->left)
15     {
16         q=p;
17         p=p->right;
18         delete(q);
19     }
20     else if(!p->right)
21     {
22         q=p;
23         p=p->left;
24         delte(q);
25     }
26     else
27     {
28         p_pre=p->left;p_pre_root=p;
29         while(p_pre->right)
30         {
31             p_pre_root=p_pre;
32             p_pre=p_pre->right;
33         }
34         p->val=p_pre->val;
35         if(p_pre_root==p) p_pre_root->left=p_pre->left;
36         else p_pre_root->right=p_pre->left;
37         delete(p_pre);
38     }
39     return true;
40 }
原文地址:https://www.cnblogs.com/lancelee98/p/11663227.html