zoukankan      html  css  js  c++  java
  • 数据结构之二叉树

    在这篇文章里面,我们主要探讨和树相关的话题。

      首先,我们来对树进行定义:树是n(n>= 0)个节点的有限集。在任何一个非空树中:(1)有且仅有一个特定的称为“根”的节点;(2)当n>1时,其余节点可分为m(m>0)个互相相关的有限集T1、T2、T3……,其中每一个集合本身又是一棵树,并且称为根的子树。

      对于我们这篇文章里讨论的二叉树,它是一种特殊的树形结构,每个节点至多只有两颗子树,并且子树有左右之分,其次序不能随意颠倒。

      接下来,我们使用java代码来定义一棵树:

     
     1 public class BinNode {
     2     private int m_Value;
     3     private BinNode m_Left;
     4     private BinNode m_Right;
     5     public void setValue(int m_Value) {
     6         this.m_Value = m_Value;
     7     }
     8     public int getValue() {
     9         return m_Value;
    10     }
    11     public void setLeft(BinNode m_Left) {
    12         this.m_Left = m_Left;
    13     }
    14     public BinNode getLeft() {
    15         return m_Left;
    16     }
    17     public void setRight(BinNode m_Right) {
    18         this.m_Right = m_Right;
    19     }
    20     public BinNode getRight() {
    21         return m_Right;
    22     }
    23     
    24     public boolean isLeaf()
    25     {
    26         return m_Left == null && m_Right == null;
    27     }
    28 }
     

      下面,开始讨论和二叉树相关的话题

    • 构造二叉树,给出一个已排序的整型数组,如何根据它来构造一个BST(二叉搜索树)。 思路:二叉搜索树的特点是左子树的值<=父节点的值<=右子树的值。我们可以从下标0开始遍历数组,然后依次创建树节点,这样下来,对于树的根节点来说,只有右子树,没有左子树,整个树不是平衡二叉树。为了优化这一点,我们可以将数组的中间元素作为根节点,前半部分的值作为树的左子树,后半部分的值作为树的右子树,然后使用递归依次构建。
       
       1 public static BinNode buildTree(int[] arrValue)
       2 {
       3     if(arrValue == null) return null;
       4     BinNode root = new BinNode();
       5     buildTree(arrValue, 0, arrValue.length - 1, root);
       6     return root;
       7 }
       8 
       9 private static void buildTree(int[] arrValue, int startPos, int endPos, BinNode tree)
      10 {
      11     if (startPos > endPos) return;
      12     
      13     int midPos = startPos + (endPos - startPos)/2;
      14     if (tree == null)
      15     {
      16         tree = new BinNode();                
      17     }
      18     tree.setValue(arrValue[midPos]);
      19     
      20     if (midPos - 1 >= startPos)
      21     {
      22         BinNode left = new BinNode();
      23         tree.setLeft(left);
      24         buildTree(arrValue, startPos, midPos - 1, left);
      25     }
      26     if (endPos >= midPos + 1)
      27     {
      28         BinNode right = new BinNode();
      29         tree.setRight(right);
      30         buildTree(arrValue, midPos + 1, endPos, right);
      31     }
      32 }
       
    • 树的遍历(前序遍历、中序遍历、后序遍历、层次遍历) 思路:可以采用递归或者非递归的方式进行遍历 前序遍历
       
       1 public static void preOrder(BinNode tree)
       2 {
       3     if (tree == null)
       4     {
       5         return;
       6     }
       7     System.out.println(tree.getValue());
       8     preOrder(tree.getLeft());
       9     preOrder(tree.getRight());
      10 }
       
       
       1 public static void preOrder2(BinNode tree)
       2 {
       3     if (tree == null) return;
       4     Stack stack = new Stack(10);
       5     BinNode temp = tree;
       6     while(temp != null)
       7     {
       8         System.out.println(temp.getValue());
       9         if (temp.getRight() != null) stack.push(temp.getRight());
      10         temp = temp.getLeft();
      11     }
      12     while(stack.get_Count() > 0)
      13     {
      14         temp = (BinNode)stack.pop();
      15         System.out.println(temp.getValue());
      16         while(temp != null)
      17         {
      18             if (temp.getRight() != null)
      19             {
      20                 stack.push(temp.getRight());
      21             }
      22             temp = temp.getLeft();
      23         }
      24     }
      25 }
       

      中序遍历

       
       1 public static void inOrder(BinNode tree)
       2 {
       3     if (tree == null)
       4     {
       5         return;
       6     }
       7     inOrder(tree.getLeft());
       8     System.out.println(tree.getValue());
       9     inOrder(tree.getRight());
      10 }
       
       
       1 public static void inOrder2(BinNode tree)
       2 {
       3     if (tree == null) return;
       4     Stack stack = new Stack(10);
       5     BinNode temp = tree;
       6     while(temp != null)
       7     {
       8         stack.push(temp);
       9         temp = temp.getLeft();
      10     }
      11     while(stack.get_Count() > 0)
      12     {
      13         temp = (BinNode)stack.pop();
      14         System.out.println(temp.getValue());
      15         if (temp.getRight() != null)
      16         {
      17             temp = temp.getRight();
      18             stack.push(temp);
      19             while(temp != null)
      20             {
      21                 if (temp.getLeft() != null)
      22                 {
      23                     stack.push(temp.getLeft());
      24                 }
      25                 temp = temp.getLeft();
      26             }
      27         }            
      28     }        
      29 }
       

      后序遍历

       
       1 public static void postOrder(BinNode tree)
       2 {
       3     if (tree == null)
       4     {
       5         return;
       6     }
       7     postOrder(tree.getLeft());
       8     postOrder(tree.getRight());
       9     System.out.println(tree.getValue());
      10 }
       
       
       1 public static void postOrder2(BinNode tree)
       2 {
       3     if (tree == null) return;
       4     Stack stack = new Stack(10);
       5     BinNode temp = tree;
       6     while(temp != null)
       7     {
       8         stack.push(temp);
       9         temp = temp.getLeft();
      10     }
      11     
      12     while(stack.get_Count() > 0)
      13     {
      14         BinNode lastVisited = temp;
      15         temp = (BinNode)stack.pop();
      16         if (temp.getRight() == null || temp.getRight() == lastVisited)
      17         {
      18             System.out.println(temp.getValue());
      19         }
      20         else if (temp.getLeft() == lastVisited)
      21         {
      22             stack.push(temp);
      23             temp = temp.getRight();
      24             stack.push(temp);
      25             while(temp != null)
      26             {
      27                 if (temp.getLeft() != null)
      28                 {
      29                     stack.push(temp.getLeft());
      30                 }
      31                 temp = temp.getLeft();
      32             }
      33         }
      34     }        
      35 }
       

      层次遍历

       
       1 public static void printTree(BinNode tree)
       2 {
       3     if (tree == null)
       4     {
       5         return;
       6     }
       7     Queue queue = new Queue(10);
       8     queue.enQueue(tree);
       9     while(queue.get_Count() > 0)
      10     {
      11         BinNode temp = (BinNode) queue.deQueue();
      12         System.out.println(temp.getValue());
      13         if (temp.getLeft() != null) queue.enQueue(temp.getLeft());
      14         if (temp.getRight() != null) queue.enQueue(temp.getRight());
      15     }        
      16 }
       
    • 判断二叉树是否是平衡二叉树 思路:平衡二叉树的特点是左右子树的深度差不能大于1,采用递归的方式。
       
       1 public static boolean isBalance(BinNode tree)
       2 {
       3     if (tree == null)
       4     {
       5         return true;
       6     }
       7     int lDepth = getDepth(tree.getLeft());
       8     int rDepth = getDepth(tree.getRight());
       9     if (lDepth - rDepth > 1 || lDepth - rDepth < -1)
      10     {
      11         return false;
      12     }
      13     return isBalance(tree.getRight()) && isBalance(tree.getLeft());
      14 }
      15 
      16 
      17 public static int getDepth(BinNode tree)
      18 {
      19     if(tree == null)
      20     {
      21         return 0;
      22     }        
      23     int lLength = getDepth(tree.getLeft());
      24     int rLength = getDepth(tree.getRight());
      25     
      26     return lLength > rLength ? lLength + 1 : rLength + 1; 
      27 }
       
    • 找出任何两个节点的最近的共同父节点 思路:用1表示根节点,2、3表示第二层节点,4、5、6、7表示第三层节点,以此类推,对于编号为n的节点,它的子节点编号为(2*n和2*n+1),通过这种方式重新标记树后,我们分别找到两个节点对应的编号,然后分别进行除2操作,直到找到相同的节点,这个节点就是最近的共同父节点。
       
       1 public static BinNode findParentNode2(BinNode tree, BinNode node1, BinNode node2)
       2 {
       3     if (tree == null) return null;
       4     BinNode result = null;
       5     int pos1 = 1, pos2 = 1;
       6     int i = 1;
       7     java.util.HashMap<Integer, BinNode> table = new java.util.HashMap<Integer, BinNode>();        
       8     BinNode temp = tree;
       9     table.put(i, temp);
      10     Queue queue = new Queue(10);
      11     queue.enQueue(i);
      12     int count = 0;
      13     while(queue.get_Count() > 0)
      14     {
      15         i = Integer.valueOf(queue.deQueue().toString());
      16         if (table.get(i) != null && table.get(i).getValue() == node1.getValue())
      17         {
      18             pos1 = i;
      19             count++;
      20         }
      21         if (table.get(i) != null && table.get(i).getValue() == node2.getValue())
      22         {
      23             pos2 = i;
      24             count++;
      25         }
      26         if(count == 2) break;
      27         
      28         if(table.get(i) == null)
      29         {
      30             table.put(2*i, null);
      31             table.put(2*i + 1, null);
      32         }
      33         else
      34         {
      35             table.put(2*i, table.get(i).getLeft());
      36             table.put(2*i + 1, table.get(i).getRight());
      37         }
      38         queue.enQueue(2*i);
      39         queue.enQueue(2*i + 1);
      40         
      41     }
      42     if (pos1 == pos2)
      43     {
      44         result = table.get(pos1);
      45     }
      46     else if(pos1 > pos2)
      47     { 
      48         while(pos1 > pos2) pos1 = pos1/2;
      49     }
      50     else
      51     {
      52         while(pos2 > pos1) pos2 = pos2/2;
      53     }
      54     if(pos1 == pos2 || pos1/2 == pos2 || pos2/2 == pos1) 
      55     {
      56         result = table.get(pos1 > pos2 ? pos2 : pos1);
      57     }
      58     else
      59     {
      60         while(pos1 != pos2) 
      61         {
      62             pos1 = pos1/2;
      63             pos2 = pos2/2;
      64         }
      65     }
      66     result = table.get(pos1);
      67     
      68     return result;
      69 }
       

      如果我们已知树是二叉排序树,那么我们可以利用二叉排序树的特点,分别寻找两个节点,在寻找过程中,将扫描过的节点放入stack中,这样可以获得两个stack,然后分别对两个stack进行pop操作,得到的第一个相同的节点就是最近的共同父节点。

       
       1 public static BinNode findParentNode(BinNode tree, BinNode node1, BinNode node2)
       2 {
       3     if (tree == null)
       4     {
       5         return null;
       6     }
       7     
       8     BinNode result = null;
       9     Stack stack1 = new Stack(10);
      10     Stack stack2 = new Stack(10);
      11     stack1.push(tree);
      12     stack2.push(tree);
      13     BinNode temp = tree;
      14     while(temp != null && temp.getValue() != node1.getValue())
      15     {
      16         stack1.push(temp);
      17         if (temp.getValue()> node1.getValue())
      18         {
      19             temp = temp.getLeft();
      20         }
      21         else
      22         {
      23             temp = temp.getRight();
      24         }
      25     }
      26     temp = tree;
      27     while(temp != null && temp.getValue() != node2.getValue())
      28     {
      29         stack2.push(temp);
      30         if (temp.getValue()> node2.getValue())
      31         {
      32             temp = temp.getLeft();
      33         }
      34         else
      35         {
      36             temp = temp.getRight();
      37         }
      38     }
      39     if (stack1.get_Count() > stack2.get_Count())
      40     {
      41         while(stack1.get_Count() > stack2.get_Count())
      42         {
      43             stack1.pop();
      44         }
      45     }
      46     if (stack2.get_Count() > stack1.get_Count())
      47     {
      48         while(stack2.get_Count()>stack1.get_Count())
      49         {
      50             stack2.pop();
      51         }
      52     }
      53     while(stack1.get_Count() > 0 && stack2.get_Count() > 0)
      54     {
      55         if (stack1.peek() == stack2.peek())
      56         {
      57             result = (BinNode)stack1.peek();
      58             break;
      59         }
      60         stack1.pop();
      61         stack2.pop();
      62     }
      63     
      64     return result;
      65 }
       
    • 找出树中节点值得和为某一值得所有路径 思路:肯定是需要使用递归来实现,使用stack来存储扫描过的路径。
       
       1 public static void findSum(BinNode tree, int sum, Stack stack)
       2 {
       3     if (tree == null) return;
       4     stack.push(tree);        
       5     if (tree.getValue() == sum)
       6     {
       7         Stack temp = new Stack(stack.get_Count());
       8         while(stack.get_Count()>0)
       9         {
      10             temp.push(stack.pop());
      11         }
      12         StringBuffer sb = new StringBuffer();
      13         while(temp.get_Count() > 0)
      14         {
      15             sb.append(((BinNode)temp.peek()).getValue()).append("->");
      16             stack.push(temp.pop());
      17         }
      18         System.out.println(sb.substring(0, sb.length() - 2));
      19     }
      20     else if (tree.getValue() < sum)
      21     {
      22         if (tree.getLeft() != null) findSum(tree.getLeft(), sum - tree.getValue(), stack);
      23         if (tree.getRight() != null) findSum(tree.getRight(), sum - tree.getValue(), stack);
      24     }
      25     stack.pop();
      26 }
       
    • 判断给定数组是否是二叉搜索树后序遍历的结果 思路:观察二叉搜索树后序遍历的特点,根节点在最后,从下标0开始扫描,直到第一个大于根节点值得下标m,[0,(m-1)]的元素是节点的左子树,[m, n]是节点的右子树,并且右子树中任何节点的值都大于根节点。这样可以使用递归的方式以此判断。
    • 相传此乃网易二面题

      要求现场手写代码判断一个数字序列是BST后序遍历的结果。

      来源1来源2

      如图所示 对于后续遍历的排序二叉树应具有上面的一个不等式性质 以及 根节点为最后一个节点的性质

      因此代码如下

      1. //序列array有n个元素  
      2. //如果这n个元素是二叉排序树的后续遍历结果 返回true  
      3. //否则 返回false  
      4. bool isBST(int * array, size_t n)  
      5. {  
      6.     assert(array != NULL);  
      7.     if (n <= 1)  
      8.     {  
      9.         return true// 有一个节点 或0个节点 符合树的性质  
      10.     }  
      11.     size_t i = 0;  
      12.     for (i = 0; i < n-1; ++i)  
      13.     {  
      14.         if (array[i] > array[n-1]) //array[n-1] 为数组最后一个元素 如果是后续遍历 应该是树的根节点。根节点应该大于左子树中的所有节点  
      15.         {  
      16.             break;  
      17.         }  
      18.     }  
      19.     if (i == n-1)  
      20.     {  
      21.         //全是左子树中的点  
      22.         return isBST(array, n-1); //判断左子树是否成立  
      23.     }  
      24.     size_t l_end = i;  
      25.     for (i; i < n-1; ++i)  
      26.     {  
      27.         if (array[i] < array[n-1])  
      28.         {  
      29.             break;      //右子树中的所有节点应该大于根节点  
      30.         }  
      31.     }  
      32.     if (i == n-1)  
      33.     {  
      34.         // 判断左右子树是否合法  
      35.         return isBST(array, l_end) && isBST(array+l_end, n - 1 - l_end);  
      36.     }  
      37.     return false;  
      38. }  
      //序列array有n个元素
      //如果这n个元素是二叉排序树的后续遍历结果 返回true
      //否则 返回false
      bool isBST(int * array, size_t n)
      {
      	assert(array != NULL);
      	if (n <= 1)
      	{
      		return true; // 有一个节点 或0个节点 符合树的性质
      	}
      	size_t i = 0;
      	for (i = 0; i < n-1; ++i)
      	{
      		if (array[i] > array[n-1]) //array[n-1] 为数组最后一个元素 如果是后续遍历 应该是树的根节点。根节点应该大于左子树中的所有节点
      		{
      			break;
      		}
      	}
      	if (i == n-1)
      	{
      		//全是左子树中的点
      		return isBST(array, n-1); //判断左子树是否成立
      	}
      	size_t l_end = i;
      	for (i; i < n-1; ++i)
      	{
      		if (array[i] < array[n-1])
      		{
      			break;		//右子树中的所有节点应该大于根节点
      		}
      	}
      	if (i == n-1)
      	{
      		// 判断左右子树是否合法
      		return isBST(array, l_end) && isBST(array+l_end, n - 1 - l_end);
      	}
      	return false;
      }
      测试

      如下的二叉排序树

      1. void test_isBST()  
      2. {  
      3.     int a[]={0};  
      4.     int *p;  
      5.     size_t n = sizeof(a)/sizeof(a[0]);  
      6.     p=a;  
      7.     n = sizeof(a)/sizeof(a[0]);  
      8.     assert(isBST(p,n) == true);  
      9.     assert(isBST(p,0) == true);  
      10.     int b[]={2,4,3,7,6,8,5};  
      11.     p=b;  
      12.     n = sizeof(b)/sizeof(b[0]);  
      13.     assert(isBST(p,n) == true);  
      14.   
      15.     //int c[]={2,4,3,8,6,7,5};  
      16.     int c[]={8,6,7};  
      17.     p=c;  
      18.     n = sizeof(c)/sizeof(c[0]);  
      19.     assert(isBST(p,n) == false);  
      20.   
      21. }  
    • 给定一颗BST,另f=(max+min)/2,寻找距离f最近但大于f的节点 思路:对于BST,最小值是最左边的叶子节点,最大值是最右边的叶子节点。
       
       1 public static BinNode findAvgInBST(BinNode tree)
       2 {
       3     if (tree == null) return null;
       4     BinNode temp = tree;
       5     while(temp.getLeft() != null) temp = temp.getLeft();
       6     int minValue = temp.getValue();
       7     temp = tree;
       8     while(temp.getRight() != null) temp = temp.getRight();
       9     int maxValue = temp.getValue();
      10     int avgValue = (minValue + maxValue)/2;
      11     return findNode(tree, avgValue);
      12 }
      13 
      14 private static BinNode findNode(BinNode tree, int value)
      15 {
      16     if (tree == null) return null;
      17     if (tree.getValue() >= value)
      18     {
      19         if (tree.getLeft() == null)
      20         {
      21             return tree;
      22         }
      23         else
      24         {
      25             BinNode temp = findNode(tree.getLeft(), value);
      26             return temp.getValue() < tree.getValue() ? temp:tree;
      27         }
      28     }
      29     else
      30     {
      31         if (tree.getRight() == null)
      32         {
      33             return tree;
      34         }
      35         else
      36         {
      37             BinNode temp = findNode(tree.getRight(), value);
      38             return temp.getValue() < tree.getValue() ? temp:tree;
      39         }
      40     }
      41 }
       
    • 给出一棵树,得到这棵树的镜像 思路:我们可以考虑前序遍历的结果:父节点->左子树->右子树,而镜像之后的结果:父节点->右子树->左子树,我们可以采用递归前序遍历的方式来实现
       
      1 public static void imageTree(BinNode tree)
      2 {
      3     if (tree == null) return;
      4     BinNode temp = tree.getLeft();
      5     tree.setLeft(tree.getRight());
      6     tree.setRight(temp);
      7     if (tree.getLeft() != null) imageTree(tree.getLeft());
      8     if (tree.getRight() != null) imageTree(tree.getRight());
      9 }
       

      我们也可以采用循环+栈的方式来实现

       
       1 public static void imageTrees(BinNode tree)
       2 {
       3     if (tree == null) return;
       4     Stack stack = new Stack(10);
       5     BinNode temp = tree;
       6     stack.push(temp);
       7     while(stack.get_Count() > 0)
       8     {
       9         temp = (BinNode)stack.pop();
      10         BinNode temp1 = temp.getLeft();
      11         temp.setLeft(temp.getRight());
      12         temp.setRight(temp1);            
      13         if (temp.getLeft() != null)
      14         {
      15             stack.push(temp.getLeft());
      16         }
      17         if (temp.getRight() != null)
      18         {
      19             stack.push(temp.getRight());
      20         }
      21     }
      22 }
       
    • 将BST转换为排序的双向链表 思路:对于BST来说,中序遍历的结果就是元素按照从小到大进行排序的结果
       
       1 public static DoubleLink convertTreeToList(BinNode tree)
       2 {
       3     if (tree == null) return null;
       4     
       5     DoubleLink list = new DoubleLink();
       6     list.setValue(null);
       7     list.setPre(null);
       8     DoubleLink listNode = list;
       9     
      10     BinNode treeNode = tree;
      11     Stack stack = new Stack(10);
      12     
      13     while(treeNode != null)
      14     {
      15         stack.push(treeNode);
      16         treeNode = treeNode.getLeft();
      17     }
      18     
      19     while(stack.get_Count() > 0)
      20     {
      21         treeNode = (BinNode)stack.pop();
      22         DoubleLink tempListNode = new DoubleLink();
      23         tempListNode.setValue(treeNode);
      24         listNode.setNext(tempListNode);
      25         tempListNode.setPre(listNode);
      26         listNode = tempListNode;
      27         if (treeNode.getRight() != null)
      28         {
      29             treeNode = treeNode.getRight();
      30             stack.push(treeNode);
      31             while(treeNode != null)
      32             {
      33                 if (treeNode.getLeft() != null)
      34                 {
      35                     stack.push(treeNode.getLeft());
      36                 }
      37                 treeNode = treeNode.getLeft();
      38             }
      39         }
      40     }
      41     
      42     listNode.setNext(null);
      43     
      44     return list;
      45 }
       

      其中DoubleLink的定义如下

       
       1 public class DoubleLink {
       2     private Object value;
       3     private DoubleLink next;
       4     private DoubleLink pre;
       5     public void setValue(Object value) {
       6         this.value = value;
       7     }
       8     public Object getValue() {
       9         return value;
      10     }
      11     public void setNext(DoubleLink next) {
      12         this.next = next;
      13     }
      14     public DoubleLink getNext() {
      15         return next;
      16     }
      17     public void setPre(DoubleLink pre) {
      18         this.pre = pre;
      19     }
      20     public DoubleLink getPre() {
      21         return pre;
      22     }    
      23
       
    • 向BST中插入节点 思路:对BST中插入节点,首先按照遍历BST,找出所插接点的父节点,然后创建新节点
       
       1 public static void addValueToBST(BinNode tree, int value)
       2 {
       3     if (tree == null)
       4     {
       5         tree = new BinNode();
       6         tree.setValue(value);
       7         return;
       8     }
       9     
      10     BinNode temp = tree;
      11     while(true)
      12     {            
      13         if (temp.getValue() >= value)
      14         {
      15             if (temp.getLeft() == null) break;
      16             temp = temp.getLeft();
      17         }
      18         else
      19         {            
      20             if (temp.getRight() == null) break;
      21             temp = temp.getRight();
      22         }
      23     }
      24     
      25     BinNode node = new BinNode();
      26     node.setValue(value);
      27     if (temp.getValue() >= value)
      28     {
      29         temp.setLeft(node);
      30     }
      31     else
      32     {
      33         temp.setRight(node);
      34     }
      35 }
       
    • 向BST中删除节点 思路:首先是要能够找到需要删除的节点,然后根据节点是否有子节点分情况处理,如果没有子树,那么直接删除该节点(从父节点上解除关联);如果只有左子树或者右子树,那么删除节点后将左子树或者右子树直接挂在父节点下;如果左右子树均存在,那么需要找出左子树的最大值或者右子树的最小值作为父节点的直接子节点,然后将这个节点的左右子树分别设置为删除节点的左右子树。
       
       1 public static void delValueFromBST(BinNode tree, int value)
       2 {
       3     if (tree == null) return;
       4     BinNode deleteNode = findNodeInBST(tree, value);
       5     BinNode parentNode = findParentNodeInBST(tree, value);
       6     if (parentNode == null || deleteNode == null) return;
       7     if (deleteNode.isLeaf())
       8     {
       9         if (parentNode.getLeft() == deleteNode) parentNode.setLeft(null);
      10         else parentNode.setRight(null);
      11     }
      12     else if (deleteNode.getLeft() == null && deleteNode.getRight() != null)
      13     {
      14         if (parentNode.getValue() >= deleteNode.getRight().getValue()) parentNode.setLeft(deleteNode.getRight());
      15         else parentNode.setRight(deleteNode.getRight());
      16         deleteNode.setRight(null);
      17     }
      18     else if (deleteNode.getLeft() != null && deleteNode.getRight() == null)
      19     {
      20         if (parentNode.getValue() >= deleteNode.getLeft().getValue()) parentNode.setLeft(deleteNode.getLeft());
      21         else parentNode.setRight(deleteNode.getLeft());
      22         deleteNode.setLeft(null);
      23     }
      24     else
      25     {
      26         BinNode temp = deleteNode.getRight();
      27         BinNode parent = deleteNode.getRight();
      28         while(temp.getLeft() != null) 
      29         {
      30             parent = temp; 
      31             temp = temp.getLeft();
      32         }
      33         if (parent != temp)
      34         {
      35             parent.setLeft(null);
      36         }
      37         temp.setLeft(deleteNode.getLeft());
      38         temp.setRight(deleteNode.getRight());
      39         if (parentNode.getValue() >= temp.getValue()) parentNode.setLeft(temp);
      40         else parentNode.setRight(temp);
      41         deleteNode.setLeft(null);
      42         deleteNode.setRight(null);
      43     }
      44 }
      45 
      46 private static BinNode findNodeInBST(BinNode tree, int value)
      47 {
      48     if (tree == null) return null;
      49     if (tree.getValue() == value) return tree;
      50     else if (tree.getValue() > value) return findNodeInBST(tree.getLeft(), value);
      51     else return findNodeInBST(tree.getRight(), value);
      52 }
      53 
      54 private static BinNode findParentNodeInBST(BinNode tree, int value)
      55 {
      56     if (tree == null) return null;
      57     if (tree.getValue() == value) return null;
      58     if ((tree.getLeft() != null && tree.getLeft().getValue() == value) || 
      59             (tree.getRight() != null &&tree.getRight().getValue() == value)) return tree;
      60     else if (tree.getValue() > value) return findParentNodeInBST(tree.getLeft(), value);
      61     else return findParentNodeInBST(tree.getRight(), value);
      62 }
       

      最后,欢迎大家提出更多和二叉树相关的面试题目,我们可以一起讨论。

  • 相关阅读:
    u-boot器件驱动模型(Device&Drivers)之uclass (转)
    u-boot下的DM驱动模型 阶梯状 (转)
    u-boot-2018.09 DTS上 I2C节点的解析 (转)
    [uboot] (番外篇)uboot串口&console&stdio设备工作流程 (转)
    [uboot] (番外篇)uboot 驱动模型(转)重要
    u-boot DM初始化流程
    【u-boot】u-boot中initf_dm()函数执行流程(转)
    【u-boot】u-boot对设备树的节点解析(转)
    BeanPostProcessor
    一些压力测试结果(Mysql,Zookeeper,Redis,Mongodb)
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3444629.html
Copyright © 2011-2022 走看看