二叉搜索树 与 平衡二叉树
定义: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 }