zoukankan      html  css  js  c++  java
  • Java基础之泛型——使用二叉树进行排序(TryBinaryTree)

    控制台程序。

    1、实现针对容器类的基于集合的循环

    为了让容器类类型的对象能够在基于集合的for循环中可用,类必须并且只需要满足一个要求——必须实现泛型接口java.lang.Iterable<>。接口Iterable<T>是声明了单个方法iterable<T>接口并且提供对iterable()方法的实现。

      1 import java.util.Iterator;
      2 
      3 public class LinkedList<T> implements Iterable<T> {
      4 
      5   // Returns an iterator for this list
      6   public Iterator<T> iterator() {
      7     return new ListIterator();                                         // Create iterator of the inner class type
      8   }
      9 
     10   // Default constructor - creates an empty list
     11   public LinkedList() {}
     12 
     13   // Constructor to create a list containing one object
     14   public LinkedList(T item) {
     15     if(item != null) {
     16       current = end = start = new ListItem(item);                      // item is the start and end
     17     }
     18   }
     19 
     20   // Construct a linked list from an array of objects
     21   public LinkedList(T[] items) {
     22     if(items != null) {
     23       // Add the items to the list
     24       for(int i = 0; i < items.length; ++i) {
     25         addItem(items[i]);
     26       }
     27       current = start;
     28     }
     29   }
     30 
     31   // Add an item object to the list
     32   public void addItem(T item) {
     33     ListItem newEnd = new ListItem(item);                              // Create a new ListItem
     34     if(start == null) {                                                // Is the list empty?
     35       start = end = newEnd;                                            // Yes, so new element is start and end
     36     } else {                                                           // No, so append new element
     37       end.next = newEnd;                                               // Set next variable for old end
     38       end = newEnd;                                                    // Store new item as end
     39     }
     40   }
     41   // Get the first object in the list
     42   public T getFirst() {
     43     current = start;
     44     return start == null ? null : start.item;
     45   }
     46 
     47   // Get the next object in the list
     48   public T getNext() {
     49     if(current != null) {
     50       current = current.next;                                          // Get the reference to the next item
     51     }
     52     return current == null ? null : current.item;
     53   }
     54 
     55   private ListItem start = null;                                       // First ListItem in the list
     56   private ListItem end = null;                                         // Last ListItem in the list
     57   private ListItem current = null;                                     // The current item for iterating
     58 
     59   private class ListItem {
     60 
     61     // Constructor
     62     public ListItem(T item) {
     63       this.item = item;                                                // Store the item
     64       next = null;                                                     // Set next as end point
     65     }
     66 
     67     // Return class name & object
     68     @Override
     69     public String toString() {
     70       return "ListItem " + item ;
     71     }
     72 
     73     ListItem next;                                                    // Refers to next item in the list
     74     T item;                                                           // The item for this ListItem
     75   }
     76 
     77   private class ListIterator implements Iterator<T> {
     78     // Constructor
     79     public ListIterator() {
     80       nextElement = getFirst();
     81     }
     82 
     83     // Method to test whether more elements are available
     84     public boolean hasNext() {
     85       return nextElement != null;
     86     }
     87 
     88     // Method to return the next available object from the linked list
     89     public T next() {
     90       T element = nextElement;
     91       if(element == null) {
     92         throw new java.util.NoSuchElementException();
     93       }
     94       nextElement = getNext();
     95         return element;
     96     }
     97 
     98     // Method to remove the last element retrieved from the linked list
     99     // You don't want to support this operation for the linked list
    100     // so just throw the exception
    101     public void remove() {
    102       throw new UnsupportedOperationException("Remove not supported for LinkedList<>");
    103     }
    104 
    105     private T nextElement;
    106   }
    107 }

    泛型LinkedList<>类类型现在实现了泛型接口类型Iterable<>,并且它们共享通用的类型参数。所以可以通过简单地实现Iterable<>接口并使用基于集合的for循环来定义包含任意类型对象集合的类,并且提供用于对内容进行迭代的功能。接口会自动被定制成能使用特定容器包含的任意类型对象。

    2、定义二叉树泛型类

     1 public class BinaryTree<T extends Comparable<T>> {
     2 
     3   // Add a value to the tree
     4   public void add(T value) {
     5     if(root == null) {                                                 // If there's no root node
     6       root = new Node(value);                                          // store it in the root
     7     } else {                                                           // Otherwise...
     8       add(value, root);                                                // add it recursively
     9     }
    10   }
    11 
    12   // Recursive insertion of an object
    13   private void add(T value, Node node) {
    14     int comparison = node.obj.compareTo(value);
    15     if(comparison == 0) {                                              // If it is equal to the current node
    16       ++node.count;                                                    // just increment the count
    17       return;
    18     }
    19     if(comparison > 0) {                                               // If it's less than the current node
    20       if(node.left == null) {                                          // and the left child node is null
    21         node.left = new Node(value);                                   // Store it as the left child node
    22       } else {                                                         // Otherwise...
    23         add(value, node.left);                                         // ... call add() again at the left node
    24       }
    25     } else {                                                           // It must be greater than the current node
    26       if(node.right == null) {                                         // so it must go to the right...
    27         node.right = new Node(value);                                  // store it as the right node
    28       } else {                                                         // ...or when right node is not null
    29         add(value, node.right);                                        // ...call add() again at the right node
    30       }
    31     }
    32   }
    33 
    34   // Create a list containing the values from the tree in sequence
    35   public LinkedList<T> sort() {
    36     LinkedList<T> values = new LinkedList<>();                         // Create a linked list
    37     treeSort(root, values);                                            // Sort the objects into the list
    38     return values;
    39   }
    40 
    41   // Extract the tree nodes in sequence
    42   private void treeSort(Node node, LinkedList<T> values) {
    43     if(node != null) {                                                 // If the current node isn't null
    44       treeSort(node.left, values);                                     // process its left child node
    45 
    46       // List the duplicate objects for the current node
    47       for(int i = 0 ; i < node.count ; ++i) {
    48         values.addItem(node.obj);
    49        }
    50       treeSort(node.right, values);                                    // Now process the right child node
    51     }
    52   }
    53 
    54   private Node root;                                                   // The root node
    55 
    56   // Private inner class defining nodes
    57   private class Node {
    58     Node(T value) {
    59       obj = value;
    60       count = 1;
    61     }
    62 
    63     T obj;                                                             // Object stored in the node
    64     int count;                                                         // Count of identical objects
    65     Node left;                                                         // The left child node
    66     Node right;                                                        // The right child node
    67   }
    68 }

    使用类型参数(用来约束参数化接口类型Comparable<T>的实现)来定义BinaryTree<T>。因此,使用BinaryTree<T>类型的任何类型参数都必须实现Comparable<T>接口。如果不这样做,代码就不会编译。这样可以确保添加到BinaryTree<T>对象的所有对象都有可用的Comparable()方法。


    3、尝试使用BianaryTree<>对象对整数和字符串进行排序

     1 public class TryBinaryTree {
     2   public static void main(String[] args) {
     3     int[] numbers = new int[30];
     4     for(int i = 0 ; i < numbers.length ; ++i) {
     5       numbers[i] = (int)(1000.0*Math.random());                        // Random integers 0 to 999
     6     }
     7 
     8     // List starting integer values
     9     int count = 0;
    10     System.out.println("Original values are:");
    11     for(int number : numbers) {
    12       System.out.printf("%6d", number);
    13       if(++count%6 == 0) {
    14         System.out.println();
    15       }
    16     }
    17 
    18     // Create the tree and add the integers to it
    19     BinaryTree<Integer> tree = new BinaryTree<>();
    20     for(int number:numbers) {
    21       tree.add(number);
    22     }
    23 
    24     // Get sorted values
    25     LinkedList<Integer> values = tree.sort();
    26     count = 0;
    27     System.out.println("
    Sorted values are:");
    28     for(Integer value : values) {
    29       System.out.printf("%6d", value);
    30       if(++count%6 == 0) {
    31         System.out.println();
    32       }
    33     }
    34 
    35     // Create an array of words to be sorted
    36     String[] words = {"vacillate", "procrastinate", "arboreal", "syzygy",
    37                       "xenocracy", "zygote"       , "mephitic", "soporific",
    38                       "grisly"   , "gristly" };
    39 
    40     // List the words
    41     System.out.println("
    Original word sequence:");
    42     for(String word : words) {
    43       System.out.printf("%-15s", word);
    44       if(++count%5 == 0) {
    45         System.out.println();
    46       }
    47     }
    48 
    49     // Create the tree and insert the words
    50     BinaryTree<String> cache = new BinaryTree<>();
    51     for(String word : words) {
    52       cache.add(word);
    53     }
    54 
    55     // Sort the words
    56     LinkedList<String> sortedWords = cache.sort();
    57 
    58     // List the sorted words
    59     System.out.println("
    Sorted word sequence:");
    60     count = 0;
    61     for(String word : sortedWords) {
    62       System.out.printf("%-15s", word);
    63       if(++count%5 == 0) {
    64         System.out.println();
    65       }
    66     }
    67   }
    68 }

    这里之所以能使用基于集合的for循环,是因为LinkedList<T>类型实现了Iterable<T>接口,这是让容器能使用这个for循环来访问元素的唯一先决条件。

  • 相关阅读:
    实现类似add(1)(2)(3)的函数
    Chrome安装助手踩坑
    升级webpack4错误处理
    vue项目埋点
    如何理解vue中的v-bind?
    不能不知道的webpack基本配置
    IE9及以下浏览器升级提示
    HTML5常用API
    css中clip属性
    Web开发展望
  • 原文地址:https://www.cnblogs.com/mannixiang/p/3420395.html
Copyright © 2011-2022 走看看