首页 > 代码库 > 寻找二叉搜索树错误的节点

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

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

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

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

第一次出现逆序对选择较大值,第二次出现的逆序对选择较小值  ---此算法只能找到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节点发生调换

技术分享

 

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