二叉树

二叉树(每个结点至多只有两个子树,并且二叉树的子树有左右之分,其次数不能任意颠倒)的性质:

  • 在二叉树的第i层上至多有2i-1个结点(i >= 1);
  • 深度为k的二叉树至多有2k-1个结点(k>=1)

二叉查找树(BST):对于树中的每一个结点,它的左子树中所有结点的值都小于该结点的值,而它的右子树中所有结点的值都大于该结点的值。

二叉查找树的表示:

1 class TreeNode<E>{
2     E element;
3     TreeNode<E> left;
4     TreeNode<E> righ;
5     public TreeNode(E e) {
6         element = e;
7     }
8 }

查找一个元素:

 1 public boolean search(E element){
 2     TreeNode<E> current = root;
 3     while(current != null){
 4         if(element < current.element){
 5             current = current.left;
 6         }
 7         else if(element > current.element){
 8             current = current.righ;
 9         }
10         else 
11             return true;
12        } 13     return false;
14 }

删除:情况一,

情况二:current结点有一个左孩子。假设rightMost指向包含current结点的左子树中最大的元素的结点,而parentOfRightMost指向rightMost结点的父结点。注意,rightMost结点不会有右孩子,但是可能会有左孩子。使用rightMost结点中的元素值替换current结点中的元素值,将parentOfRightMost结点和rightMost结点的左孩子相连,然后删除rightMost结点,

注意:如果current的左孩子没有右孩子,那么current.left指向current左子树的最大元素。在这种情况下,rightMost是current.left,而parentOfRightMost是current。

 1   /** Delete an element from the binary tree.
 2    * Return true if the element is deleted successfully
 3    * Return false if the element is not in the tree */
 4   public boolean delete(E e) {
 5     // Locate the node to be deleted and also locate its parent node
 6     TreeNode<E> parent = null;
 7     TreeNode<E> current = root;
 8     while (current != null) {
 9       if (e.compareTo(current.element) < 0) {
10         parent = current;
11         current = current.left;
12       }
13       else if (e.compareTo(current.element) > 0) {
14         parent = current;
15         current = current.right;
16       }
17       else
18         break; // Element is in the tree pointed by current
19     }
20 
21     if (current == null)
22       return false; // Element is not in the tree
23 
24     // Case 1: current has no left children
25     if (current.left == null) {
26       // Connect the parent with the right child of the current node
27       if (parent == null) {
28         root = current.right;
29       }
30       else {
31         if (e.compareTo(parent.element) < 0)//确定要删除的结点是其父结点的左孩子还是右孩子?
32           parent.left = current.right;
33         else
34           parent.right = current.right;
35       }
36     }
37     else {
38       // Case 2: The current node has a left child
39       // Locate the rightmost node in the left subtree of
40       // the current node and also its parent
41       TreeNode<E> parentOfRightMost = current;
42       TreeNode<E> rightMost = current.left;
43 
44       while (rightMost.right != null) {
45         parentOfRightMost = rightMost;
46         rightMost = rightMost.right; // Keep going to the right找出值最大的结点
47       }
48 
49       // Replace the element in current by the element in rightMost
50       current.element = rightMost.element;
51 
52       // Eliminate rightmost node 删除元素值最大的结点
53       if (parentOfRightMost.right == rightMost)
54         parentOfRightMost.right = rightMost.left;
55       else
56         // Special case: parentOfRightMost == current
//如果current的左孩子没有右孩子,那么current.left指向current左子树的最大元素。在这种情况下,rightMost是current.left,而parentOfRightMost是current。
57 parentOfRightMost.left = rightMost.left; 58 } 59 60 size--; 61 return true; // Element inserted 62 }

 

 

BinaryTree的实现

  1. 接口Tree:Tree.java
     1 public interface Tree<E extends Comparable<E>> {
     2   /** Return true if the element is in the tree */
     3   public boolean search(E e);
     4 
     5   /** Insert element o into the binary tree
     6    * Return true if the element is inserted successfully */
     7   public boolean insert(E e);
     8 
     9   /** Delete the specified element from the tree
    10    * Return true if the element is deleted successfully */
    11   public boolean delete(E e);
    12 
    13   /** Inorder traversal from the root*/
    14   public void inorder();
    15 
    16   /** Postorder traversal from the root */
    17   public void postorder();
    18 
    19   /** Preorder traversal from the root */
    20   public void preorder();
    21 
    22   /** Get the number of nodes in the tree */
    23   public int getSize();
    24 
    25   /** Return true if the tree is empty */
    26   public boolean isEmpty();
    27 
    28   /** Return an iterator to traverse elements in the tree */
    29   public java.util.Iterator iterator();
    30 }
    View Code

     

  2. 抽象类Abstract类:AbstractTree.java
     1 public abstract class AbstractTree<E extends Comparable<E>>
     2     implements Tree<E> {
     3   /** Inorder traversal from the root*/
     4   public void inorder() {
     5   }
     6 
     7   /** Postorder traversal from the root */
     8   public void postorder() {
     9   }
    10 
    11   /** Preorder traversal from the root */
    12   public void preorder() {
    13   }
    14 
    15   /** Return true if the tree is empty */
    16   public boolean isEmpty() {
    17     return getSize() == 0;
    18   }
    19 
    20   /** Return an iterator to traverse elements in the tree */
    21   public java.util.Iterator iterator() {
    22     return null;
    23   }
    24 }
    View Code

     

  3. 具体实现BinaryTree类:BinaryTree.java
      1 public class BinaryTree<E extends Comparable<E>>
      2     extends AbstractTree<E> {
      3   protected TreeNode<E> root;
      4   protected int size = 0;
      5 
      6   /** Create a default binary tree */
      7   public BinaryTree() {
      8   }
      9 
     10   /** Create a binary tree from an array of objects */
     11   public BinaryTree(E[] objects) {
     12     for (int i = 0; i < objects.length; i++)
     13       insert(objects[i]);
     14   }
     15 
     16   /** Returns true if the element is in the tree */
     17   public boolean search(E e) {
     18     TreeNode<E> current = root; // Start from the root
     19 
     20     while (current != null) {
     21       if (e.compareTo(current.element) < 0) {
     22         current = current.left;
     23       }
     24       else if (e.compareTo(current.element) > 0) {
     25         current = current.right;
     26       }
     27       else // element matches current.element
     28         return true; // Element is found
     29     }
     30 
     31     return false;
     32   }
     33 
     34   /** Insert element o into the binary tree
     35    * Return true if the element is inserted successfully */
     36   public boolean insert(E e) {
     37     if (root == null)
     38       root = createNewNode(e); // Create a new root
     39     else {
     40       // Locate the parent node
     41       TreeNode<E> parent = null;
     42       TreeNode<E> current = root;
     43       while (current != null)
     44         if (e.compareTo(current.element) < 0) {
     45           parent = current;
     46           current = current.left;
     47         }
     48         else if (e.compareTo(current.element) > 0) {
     49           parent = current;
     50           current = current.right;
     51         }
     52         else
     53           return false; // Duplicate node not inserted
     54 
     55       // Create the new node and attach it to the parent node
     56       if (e.compareTo(parent.element) < 0)
     57         parent.left = createNewNode(e);
     58       else
     59         parent.right = createNewNode(e);
     60     }
     61 
     62     size++;
     63     return true; // Element inserted
     64   }
     65 
     66   protected TreeNode<E> createNewNode(E e) {
     67     return new TreeNode<E>(e);
     68   }
     69 
     70   /** Inorder traversal from the root*/
     71   public void inorder() {
     72     inorder(root);
     73   }
     74 
     75   /** Inorder traversal from a subtree */
     76   protected void inorder(TreeNode<E> root) {//中序遍历
     77     if (root == null) return;
     78     inorder(root.left);
     79     System.out.print(root.element + " ");
     80     inorder(root.right);
     81   }
     82 
     83   /** Postorder traversal from the root */
     84   public void postorder() {
     85     postorder(root);
     86   }
     87 
     88   /** Postorder traversal from a subtree */
     89   protected void postorder(TreeNode<E> root) {//后序遍历
     90     if (root == null) return;
     91     postorder(root.left);
     92     postorder(root.right);
     93     System.out.print(root.element + " ");
     94   }
     95 
     96   /** Preorder traversal from the root */
     97   public void preorder() {
     98     preorder(root);
     99   }
    100 
    101   /** Preorder traversal from a subtree */
    102   protected void preorder(TreeNode<E> root) {//前序遍历
    103     if (root == null) return;
    104     System.out.print(root.element + " ");
    105     preorder(root.left);
    106     preorder(root.right);
    107   }
    108 
    109   /** Inner class tree node */
    110   public static class TreeNode<E extends Comparable<E>> {
    111     E element;
    112     TreeNode<E> left;
    113     TreeNode<E> right;
    114 
    115     public TreeNode(E e) {
    116       element = e;
    117     }
    118   }
    119 
    120   /** Get the number of nodes in the tree */
    121   public int getSize() {
    122     return size;
    123   }
    124 
    125   /** Returns the root of the tree */
    126   public TreeNode getRoot() {
    127     return root;
    128   }
    129 
    130   /** Returns a path from the root leading to the specified element */
    131   public java.util.ArrayList<TreeNode<E>> path(E e) {//输出从根结点到e的路径
    132     java.util.ArrayList<TreeNode<E>> list =
    133       new java.util.ArrayList<TreeNode<E>>();
    134     TreeNode<E> current = root; // Start from the root
    135 
    136     while (current != null) {
    137       list.add(current); // Add the node to the list
    138       if (e.compareTo(current.element) < 0) {
    139         current = current.left;
    140       }
    141       else if (e.compareTo(current.element) > 0) {
    142         current = current.right;
    143       }
    144       else
    145         break;
    146     }
    147 
    148     return list; // Return an array of nodes
    149   }
    150 
    151   /** Delete an element from the binary tree.
    152    * Return true if the element is deleted successfully
    153    * Return false if the element is not in the tree */
    154   public boolean delete(E e) {
    155     // Locate the node to be deleted and also locate its parent node
    156     TreeNode<E> parent = null;
    157     TreeNode<E> current = root;
    158     while (current != null) {
    159       if (e.compareTo(current.element) < 0) {
    160         parent = current;
    161         current = current.left;
    162       }
    163       else if (e.compareTo(current.element) > 0) {
    164         parent = current;
    165         current = current.right;
    166       }
    167       else
    168         break; // Element is in the tree pointed by current
    169     }
    170 
    171     if (current == null)
    172       return false; // Element is not in the tree
    173 
    174     // Case 1: current has no left children
    175     if (current.left == null) {
    176       // Connect the parent with the right child of the current node
    177       if (parent == null) {
    178         root = current.right;
    179       }
    180       else {
    181         if (e.compareTo(parent.element) < 0)
    182           parent.left = current.right;
    183         else
    184           parent.right = current.right;
    185       }
    186     }
    187     else {
    188       // Case 2: The current node has a left child
    189       // Locate the rightmost node in the left subtree of
    190       // the current node and also its parent
    191       TreeNode<E> parentOfRightMost = current;
    192       TreeNode<E> rightMost = current.left;
    193 
    194       while (rightMost.right != null) {
    195         parentOfRightMost = rightMost;
    196         rightMost = rightMost.right; // Keep going to the right
    197       }
    198 
    199       // Replace the element in current by the element in rightMost
    200       current.element = rightMost.element;
    201 
    202       // Eliminate rightmost node
    203       if (parentOfRightMost.right == rightMost)
    204         parentOfRightMost.right = rightMost.left;
    205       else
    206         // Special case: parentOfRightMost == current
    207         parentOfRightMost.left = rightMost.left;     
    208     }
    209 
    210     size--;
    211     return true; // Element inserted
    212   }
    213 
    214   /** Obtain an iterator. Use inorder. */
    215   public java.util.Iterator iterator() {
    216     return inorderIterator();
    217   }
    218 
    219   /** Obtain an inorder iterator */
    220   public java.util.Iterator inorderIterator() {
    221     return new InorderIterator();
    222   }
    223 
    224   // Inner class InorderIterator中序迭代器
    225   class InorderIterator implements java.util.Iterator {
    226     // Store the elements in a list
    227     private java.util.ArrayList<E> list =
    228       new java.util.ArrayList<E>();
    229     private int current = 0; // Point to the current element in list
    230 
    231     public InorderIterator() {
    232       inorder(); // Traverse binary tree and store elements in list
    233     }
    234 
    235     /** Inorder traversal from the root*/
    236     private void inorder() {
    237       inorder(root);
    238     }
    239 
    240     /** Inorder traversal from a subtree */
    241     private void inorder(TreeNode<E> root) {
    242       if (root == null)return;
    243       inorder(root.left);
    244       list.add(root.element);
    245       inorder(root.right);
    246     }
    247 
    248     /** Next element for traversing? */
    249     public boolean hasNext() {
    250       if (current < list.size())
    251         return true;
    252 
    253       return false;
    254     }
    255 
    256     /** Get the current element and move cursor to the next */
    257     public Object next() {
    258       return list.get(current++);
    259     }
    260 
    261     /** Remove the current element and refresh the list */
    262     public void remove() {
    263       delete(list.get(current)); // Delete the current element
    264       list.clear(); // Clear the list
    265       inorder(); // Rebuild the list
    266     }
    267   }
    268 
    269   /** Remove all elements from the tree */
    270   public void clear() {
    271     root = null;
    272     size = 0;
    273   }
    274 }
    View Code

     

posted @ 2013-11-14 21:53  soul390  阅读(268)  评论(0)    收藏  举报