zoukankan      html  css  js  c++  java
  • 二叉搜索树 与 平衡二叉树

    定义: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 }
  • 相关阅读:
    岳麓山岳麓书院
    花洲书院
    《诫子书》诸葛亮
    AI ML DL
    台湾大学林轩田机器学习基石
    LeNet
    VGGNet
    AlexNet 2012
    AS 中 Plugin for Gradle 和 Gradle 之间的版本对应关系
    AndroidStudio、gradle、buildToolsVersion关系
  • 原文地址:https://www.cnblogs.com/lancelee98/p/11663227.html
Copyright © 2011-2022 走看看