二叉搜索树中找出比K大的最小的那个数

这是一道面试的算法题,题目不难,但是在面试的时候是要求直接在白板上写程序,感觉自己还是弱爆了。第一次体验这种面试方式,虽然被虐,但是感觉还是挺好的,这方面的经验还是需要积累。

题目: 在一个二叉搜索树种查找比某个数(K)大数中最小的那个。

先把二叉树相关的构造代码贴上,下面是二叉树的节点定义。

/**
*节点
*/
public class Node {
    private int data;
    private Node lChild, rChild;

    public Node (int data){
        this.data = data;
        this.lChild = null;
        this.rChild = null;
    }

    public Node(int data, Node l, Node r){
        this.data = data;
        this.rChild = r;
        this.lChild = l;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getLChild() {
        return lChild;
    }

    public void setLChild(Node lChild) {
        this.lChild = lChild;
    }

    public Node getRChild() {
        return rChild;
    }

    public void setRChild(Node rChild) {
        this.rChild = rChild;
    }


}

下面是二叉树定义, 构造,以及三种遍历方法。

public class BinTree {
    private Node root;

    public BinTree(){
        root = null;
    }

    /**
     * 创建搜索二叉树
     * @param node
     * @param data
     */ 
    private void BuildBinTree(Node node, int data){
        if(root == null){
            root = new Node(data);
        }else{
            if(data > node.getData()){
                if(node.getRChild() == null)
                    node.setRChild(new Node(data));
                else
                    BuildBinTree(node.getRChild(), data);
            }else{
                if(node.getLChild() == null)
                    node.setLChild(new Node(data));
                else
                    BuildBinTree(node.getLChild(), data);
            }

        }
    }

    public void BuildBinTree(int[] arr){
        for(int i:arr)
            BuildBinTree(root, i);      
    }

    public Node getRoot() {
        return root;
    }

    public void setRoot(Node root) {
        this.root = root;
    }

    /**
     * 递归_先序遍历
     * @param node
     */
    public void PreOrderTraverse(){

        if(root != null){
            System.out.print("先序遍历:");
            this.PreOrderTraverse(root);
            System.out.println();

        }else
            System.out.println("Error! This tree is empty...");
    }
    private void PreOrderTraverse(Node node){
        if(node != null){
        System.out.print(node.getData()+" ");
        PreOrderTraverse(node.getLChild());
        PreOrderTraverse(node.getRChild());
        }

    }

    /**
     * 递归_中序遍历
     * @param node
     */
    public void InOrderTraverse(){
        if(root != null){
            System.out.print("中序遍历:");
            this.InOrderTraverse(root);
            System.out.println();

        }else
            System.out.println("Error! This tree is empty...");
    }
    private void InOrderTraverse(Node node){
        if(node != null){
            InOrderTraverse(node.getLChild());
            System.out.print(node.getData()+" ");
            InOrderTraverse(node.getRChild());
        }
    }

首先对于这个题目,最小白的方法就是把二叉树变成一个有序数组(中序遍历)O(n),在有序数组中进行二分查找O(logn)。
这里重点是第二种方法,在树结构中进行查找, 感觉这个问题,和二叉树中插入新节点的过程是类似的,大致如下:

  1. 定义节点node, 并将根节点赋值给node;
  2. 如果node.data > K, 将node.data暂存在临时变量中,并转向左子树;
  3. 如果node.data < K , 转向右子树;
  4. 重复步骤2和步骤3直到叶子节点

这里需要注意的是,必须要遍历到叶子节点,这个过程其实就是一个二分查找的过程,复杂度O(logn).这里我设置了一个标记,就是如果是空树则返回 0.


    /**
     * 查找比key大的最小的数
     * @param tree:二叉搜索树
     * @param key:要查找的数
     * @return:返回最终值
     */
    public static int FindMinOfMax(BinTree tree, int key){
        Node node = tree.getRoot();
        int temp = 0;
        if(node == null)
            return temp;
        while(node != null){
            if(node.getData() > key)
                temp = node.getData();
            if(node.getData() > key){
                node = node.getLChild();
            }else{
                node = node.getRChild();
            }
            if(node == null)
                break;
        }

        return temp;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值