剑指offer62 二叉搜索树的第k个结点


剑指offer62

二叉搜索树的第k个结点

题目描述

给定一棵二叉搜索树,请找出其中的第k小的结点

示例

输入

{5,3,7,2,4,6,8},3

输出

{4}

思路

二叉搜索树按照中序遍历的顺序打印出来正好就是排序好的顺序。

所以,按照中序遍历顺序找到第k个结点就是结果。

代码1:递归

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

public class Solution {
    int index = 0;
    TreeNode KthNode(TreeNode pRoot, int k)
    {
        if(pRoot!=null){
            TreeNode node = KthNode(pRoot.left,k);
            if(node!=null)return node;
            index++;
            if(index==k)return pRoot;
            node = KthNode(pRoot.right,k);
            if(node!=null)return node;
        }
        return null;
    }
}

/**
思路:
//二叉搜索树按照中序遍历的顺序打印出来正好就是排序好的顺序。
//所以,按照中序遍历顺序找到第k个结点就是结果。
*/

上述代码首先执行 Kt(5,3),Kt(3,3),Kt(2,3),Kt(null,3),此时pRoot=null,执行return null, 返回到调用处TreeNode node = KthNode(pRoot.left,k),此时,pRoot=2,

然后顺序执行,if(node!=null) return node index=1, 然后执行2的右结点Kt(null,3),结点为null,执行return null, 返回node = KthNode(pRoot.right,k),此时,pRoot=null,顺序执行return null,返回TreeNode node = KthNode(pRoot.left,k),此时,pRoot=3node=null,注意 这里的 return null 执行了两次! 第一次返回右结点调用处,第二次返回左结点调用处。

顺序执行 index=2,node = KthNode(pRoot.right,k)Kt(4,3),然后执行TreeNode node = KthNode(pRoot.left,k),… ,最终执行到

if(index==k)return pRoot;
node = KthNode(pRoot.right,k);
if(node!=null)return node;
TreeNode node = KthNode(pRoot.left,k);

然后,将 pRoot=4 返回。

代码2:利用栈

此外,可考虑用栈实现遍历:

https://blog.csdn.net/sunshineoe/article/details/109899318

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}
*/
import java.util.*;
//使用的栈进行遍历
public class Solution {
    TreeNode KthNode(TreeNode pRoot, int k)
    {
      //计数器,记录的是第count小的元素
          int count = 0;
          if(pRoot == null || k <= 0){
              return null;
          }
          // 定义栈进行存储数据
          Stack<TreeNode> stack = new Stack<>();
          TreeNode node = pRoot;
          // 栈不空,结点不为空
          while(!stack.isEmpty() || node != null){
              // 如果结点不为空,
              if(node != null){
                  //将当前结点的左子树结点入栈
                  stack.push(node);
                  //结点继续移动到左边的子结点
                  node = node.left;
              }else{
                /**
                  当前结点不为空的时候,当点结点出栈,
                  判断出栈后的元素是否有右结点,有右节点指向右节点
                  结点不为空的话进栈,类似的步骤
                */
                // 出栈弹出的元素,就是按照从小到大的顺序输出的最小值。
                node = stack.pop();
                // 每弹出一个元素,计数器计数一次
                count++;
                // 计数器的大小等于K的时候,返回第k小的元素
                if(count == k){
                  return node;
                }
                node = node.right;
              }
          }
      return null;
    }
}

附:二叉搜索树实现

https://www.cnblogs.com/yahuian/p/10813614.html

以下程序可供调试,查看递归算法的流程(需在maven项目中引入test依赖)

import org.junit.jupiter.api.Test;

public class BinarySearchTree
{ // 二叉搜索树类
    private class TreeNode
    { // 节点类
        int data; // 数据域
        TreeNode right; // 右子树
        TreeNode left; // 左子树
    }

    private TreeNode root; // 树根节点

    public void insert(int key)
    {
        TreeNode p=new TreeNode(); //待插入的节点
        p.data=key;

        if(root==null)
        {
            root=p;
        }
        else
        {
            TreeNode parent;
            TreeNode current=root;
            while(true)
            {
                parent=current;
                if(key>current.data)
                {
                    current=current.right; // 右子树
                    if(current==null)
                    {
                        parent.right=p;
                        return;
                    }
                }
                else //本程序没有做key出现相等情况的处理,暂且假设用户插入的节点值都不同
                {
                    current=current.left; // 左子树
                    if(current==null)
                    {
                        parent.left=p;
                        return;
                    }
                }
            }
        }
    }


    @Test
    public void test(){
        BinarySearchTree tree=new BinarySearchTree();

        tree.insert(5);
        tree.insert(3);
        tree.insert(7);
        tree.insert(2);
        tree.insert(4);
        tree.insert(6);
        tree.insert(8);


        System.out.println(KthNode(tree.root,3));

    }


    int index = 0;
    TreeNode KthNode(TreeNode pRoot, int k)
    {
        if(pRoot!=null){
            TreeNode node = KthNode(pRoot.left,k);
            if(node!=null)return node;
            index++;
            if(index==k)return pRoot;
            node = KthNode(pRoot.right,k);
            if(node!=null)return node;
        }
        return null;
    }
}

文章作者: Hailong Gao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hailong Gao !
评论
  目录