寻找二叉搜索树错误的节点

一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请找到这两个错误节点并返回他们的值。保证二叉树中结点的值各不相同。

给定一棵树的根结点,请返回两个调换了位置的值,其中小的值在前。

第一种方式:采用递归的方式---加大其运算效率

第一次出现逆序对选择较大值,第二次出现的逆序对选择较小值  ---此算法只能找到2对出现 错误的位置

 1 import java.util.*;
 2
 3 /*
 4 public class TreeNode {
 5     int val = 0;
 6     TreeNode left = null;
 7     TreeNode right = null;
 8     public TreeNode(int val) {
 9         this.val = val;
10     }
11 }*/
12 public class FindErrorNode {
13     public int[] findError(TreeNode root) {
14         // write code here 采用的是递归的形式
15         if(root==null) return null;
16         ArrayList<Integer> arr=new ArrayList<Integer>();
17         Order(root,arr);
18
19         int [] res_index=new int[2];
20         int [] res=new int[2];
21         int count=0; boolean is=true;
22         //第一次出现逆序对选择较大位置,第二次出现逆序对选择较小位置
23         for(int i=0;i<arr.size()-1;i++)
24         {
25            int diff=arr.get(i+1)-arr.get(i);
26             if(diff<0)
27             {
28                 if(is)
29                    {
30                       res_index[count++]=i;
31                       is=false;
32                    }
33                 else
34                      {
35                        res_index[count++]=i+1;is=true;
36                      }
37
38             }
39         }
40
41         if(count<2)
42           {
43             res_index[count]=res_index[0]+1;
44         }
45
46
47
48             res[0]=arr.get(res_index[1]);
49             res[1]=arr.get(res_index[0]);
50         return res;
51
52     }
53     public void Order(TreeNode root,ArrayList<Integer> arr)
54      {
55          if(root==null) return ;
56
57          if(root.left!=null)  Order(root.left,arr);
58             arr.add(root.val);
59          if(root.right!=null) Order(root.right,arr);
60     }
61 }

第二种:使用非递归进行中序遍历

 1 if(root==null) return null;
 2             int [] res=new int[2];
 3             LinkedList<TreeNode> stack=new LinkedList<>();//保证堆栈先进后出的特性
 4              TreeNode[] errornodes=new TreeNode[2];
 5             stack.add(root);TreeNode prenode=null;
 6             while(!stack.isEmpty())
 7             {
 8                 //非递归 将左子树root 节点压入stack中
 9                 while(root!=null)
10                 {
11                     root=root.left;
12                     if(root!=null)
13                         stack.add(root);
14                 }
15
16                 root=stack.removeLast();// stack 中最末尾元素
17
18                 if(prenode!=null && prenode.val>root.val)// stack 记录父节点,出现问题 父节点比左孩子树大
19                 {
20                     // 第一次出现逆序对,选择前节点,如果出现第二个逆序对,选择后节点
21                     errornodes[0]=(errornodes[0]==null?prenode:errornodes[0]);
22                     errornodes[1]=root;
23
24                 }
25
26                 prenode=root;
27                 root=root.right;
28                 if(root!=null)
29                     stack.add(root);
30             }
31
32             res[0]=errornodes[1].val;
33             res[1]=errornodes[0].val;
34             return res;

如果对其进行修改--查找到多处出现处错误的 二叉搜索树点:

1. 使用层次遍历或者

 1  public static int[] findError(TreeNode root)
 2         {
 3             if(root==null) return null;
 4             int [] res=new int[2];
 5             LinkedList<TreeNode> stack=new LinkedList<>();//保证堆栈先进后出的特性
 6              TreeNode[] errornodes=new TreeNode[10];
 7             stack.add(root);TreeNode prenode=null;
 8
 9             int count=1;
10             while(!stack.isEmpty())
11             {
12                 //非递归 将左子树root 节点压入stack中
13                 while(root!=null)
14                 {
15                     root=root.left;
16                     if(root!=null)
17                         stack.add(root);
18                 }
19
20                 root=stack.removeLast();// stack 中最末尾元素
21
22                 if(prenode!=null && prenode.val>root.val)// stack 记录父节点,出现问题 父节点比左孩子树大
23                 {
24                     // 第一次出现逆序对,选择前节点,如果出现第二个逆序对,选择后节点
25                     errornodes[0]=(errornodes[0]==null?prenode:errornodes[0]);
26                     errornodes[count++]=root;
27
28                 }
29
30                 prenode=root;
31                 root=root.right;
32                 if(root!=null)
33                     stack.add(root);
34             }
35
36
37             for(int i=0;i<count;i++)
38             {
39                 System.out.print(errornodes[i].val+" ");
40             }
41             return res;
42
43         }

输入树:int array[]={5,3,6,-1,-1,2,-1,-1,1,-1,-1}; 6节点值与1 节点值发生调换;3节点值与2节点发生调换

时间: 2024-08-26 17:30:29

寻找二叉搜索树错误的节点的相关文章

[CareerCup] 4.6 Find Next Node in a BST 寻找二叉搜索树中下一个节点

4.6 Write an algorithm to find the'next'node (i.e., in-order successor) of a given node in a binary search tree. You may assume that each node has a link to its parent.

求二叉搜索树的前驱节点和后继节点

前驱结点:节点val值小于该节点val值并且值最大的节点 后继节点:节点val值大于该节点val值并且值最小的节点 二叉树的节点val值是按照二叉树中序遍历顺序连续设定. 前驱结点 如图4的前驱结点是3 2的前驱结点是1 6的前驱结点是5 后继节点 7的后继结点是8 5的后继节点是6 2的后继节点是3 前驱节点 若一个节点有左子树,那么该节点的前驱节点是其左子树中val值最大的节点(也就是左子树中所谓的rightMostNode) 若一个节点没有左子树,那么判断该节点和其父节点的关系 2.1 若

C++二叉搜索树(带父亲节点,2种节点删除方法的比较.)

这里写代码片#include <iostream> #include <iomanip> using namespace std; template<typename Type> class BSTNode { public: Type data; BSTNode<Type> *left; BSTNode<Type> *right; BSTNode<Type> *parent;//带父亲节点的搜索二叉树. BSTNode(Type d

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的&#160;key&#160;对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用

一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点: 如果找到了,删除它. 说明: 要求算法时间复杂度为 O(h),h 为树的高度. 示例: root = [5,3,6,2,4,null,7] key = 3 5 / 3 6 / \ 2 4 7 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它. 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示. 5 / 4 6 / 2 7 另一个正确答案是 [5,2,6,null,4,null,7]. 5

用Python实现数据结构之二叉搜索树

二叉搜索树 二叉搜索树是一种特殊的二叉树,它的特点是: 对于任意一个节点p,存储在p的左子树的中的所有节点中的值都小于p中的值 对于任意一个节点p,存储在p的右子树的中的所有节点中的值都大于p中的值 一个图例: 基于二叉搜索树的这种关系,我们可以用它来实现有序映射 遍历二叉搜索树 基于二叉搜索树的特性,采用中序遍历的方式可以使得遍历结果是按照从小到大的顺序排列的.了解中序遍历可以参考用Python实现数据结构之树 这里还需要思考的一个内容是在基于中序遍历的前提下,如何求一个节点的后继节点或前驱节

Leetcode 450.删除二叉搜索树的节点

删除二叉搜索树的节点 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变.返回二叉搜索树(有可能被更新)的根节点的引用. 一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点: 如果找到了,删除它. 说明: 要求算法时间复杂度为 O(h),h 为树的高度. 示例: root = [5,3,6,2,4,null,7] key = 3 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它. 一个正确的答案

LeetCode.938-范围内求二叉搜索树节点值之和(Range Sum of BST)

这是悦乐书的第359次更新,第386篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第221题(顺位题号是938).给定二叉搜索树的根节点,返回节点值在[L,R]之间的所有节点的值的总和.二叉搜索树的节点值唯一.例如: 输入:root = [10,5,15,3,7,null,18],L = 7,R = 15 输出:32 输入:root = [10,5,15,3,7,13,18,1,null,6],L = 6,R = 10 输出:23 注意: 树中的节点数最多为1000

二叉搜索树(Java实现)

二叉搜索树基本操作 求树中的结点个数 判断节点是否为空 向树中插入新结点key-value 树中是否存在key 返回树中key对应的value值 先序遍历 中序遍历 后续遍历 层序遍历 求树中key最小的结点 求树中key最大的结点 删除树中key最小的结点 删除树中key最大的结点 树中删除一个结点 代码: /** * @param <Key> 键的泛型 * @param <Value> 值的泛型 */ public class BinarySearchTree<Key e

[Swift]LeetCode450. 删除二叉搜索树中的节点 | Delete Node in a BST

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST. Basically, the deletion can be divided into two stages: Search for a node to remove. If the n