查找--二叉排序树

1.查询操作,查询是否有某一值

class TreeNode{
	TreeNode left;
	TreeNode right;
	int  val;
}
public static boolean search(TreeNode root,int key,TreeNode parent,TreeNode out) {
		if(root==null) {//查询失败
			out=parent;
			return false;
		}
		if(key==root.val) {
			out=root;
			return true;
		}
		if(key<root.val) {
			return search(root.left,key,root,out);
		}
		if(key>root.val) {
			return search(root.right, key, parent, out);
		}
		return false;
	}

2.二叉树插入节点

public boolean insert(TreeNode root,int key) 
	{
		TreeNode leaf=new TreeNode();//对key作查询之后定位到的叶子节点
		if(!search(root, key, null, leaf)) 
		{//不存在值等于key的节点
			TreeNode sNode=new TreeNode();
			sNode.val=key;
			sNode.left=null;
			sNode.right=null;
			if(leaf==null) {
				root=sNode;//假如原树为空,即root==null
			}
			if(key<leaf.val) {
				leaf.left=sNode;
			}else {
				leaf.right=sNode;
			}
			return true;
		}else
		{
			//已存在该节点
			return false;
		}
	}

3.删除节点
删除情况分为三种:
(1)删除点为叶子节点,直接删除。
(2)删除节点只有左子树或只有右子树,独子节点继承父节点。
(3)删除节点左右子树都存在。思路:找到删除节点的最大前驱或者最小后继来替换该节点。即找到该节点左子树的最大值或者找到该节点右子树的最小值。该点的位置不变,****只是把该点的值变成最大前驱或最小后继的值,实际 上删除的点为他的最大前驱或最小后继

/*
假设P为要删除的点
*/
public static void delete(TreeNode P) {
		TreeNode Q=new TreeNode();
		TreeNode S=new TreeNode();
		if(P.right==null)
		{//右子树为空,则直接左子树子承父业
			Q=P.left;
			if(P.val<P.parent.val) {//判断原节点是父节点的左树还是右树
				P.parent.left=Q;
			}else {
				P.parent.right=Q;
			}
		}else if(P.left==null)
		{
			Q=P.right;
			if(P.val<P.parent.val) {//判断原节点是父节点的左树还是右树
				P.parent.left=Q;
			}else {
				P.parent.right=Q;
			}
		}else //左右都不为空,去找最大前驱
		{
			Q=P;
			S=P.left;
			while(S.right!=null) {
				Q=S;
				S=S.right;
			}
			//将S的值赋给P
			P.val=S.val;
			if(P!=Q)
			{//重接Q的右子树
				Q.right=S.left;
			}else
			{//重接Q的左子树
				Q.left=S.left;
			}
		}
	}

删除示意图,(参考大话数据结构P325)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述: 给定一棵二叉排序树和一个值,求该值在树中出现的次数。 输入格式: 第一行包含整数 n,表示树中节点个数。 接下来 n 行,每行包含一个整数,表示当前节点的值。 最后一行包含一个整数x,表示需要统计出现次数的值。 输出格式: 共一行,包含一个整数,表示该值在树中出现的次数。 输入样例: ``` 5 2 1 2 3 4 2 ``` 输出样例: ``` 2 ``` 算法1: 递归遍历,统计值出现的次数。 时间复杂度 平均时间复杂度为O(logn),最坏时间复杂度为O(n)。 参考文献 Python 代码 ```python class TreeNode(object): def __init__(self, x): self.val = x self.left = None self.right = None class Solution(object): def searchBST(self, root, val): """ :type root: TreeNode :type val: int :rtype: bool """ if not root: return 0 if val == root.val: return 1 + self.searchBST(root.left, val) + self.searchBST(root.right, val) elif val < root.val: return self.searchBST(root.left, val) else: return self.searchBST(root.right, val) ``` 算法2: 迭代遍历,统计值出现的次数。 时间复杂度 平均时间复杂度为O(logn),最坏时间复杂度为O(n)。 参考文献 Python 代码 ```python class TreeNode(object): def __init__(self, x): self.val = x self.left = None self.right = None class Solution(object): def searchBST(self, root, val): """ :type root: TreeNode :type val: int :rtype: bool """ if not root: return 0 count = 0 stack = [root] while stack: node = stack.pop() if node.val == val: count += 1 if node.left and node.val >= val: stack.append(node.left) if node.right and node.val <= val: stack.append(node.right) return count ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值