Java基础之泛型——使用二叉树进行排序(TryBinaryTree)

时间:2022-09-18 00:01:41

控制台程序。

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

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

 import java.util.Iterator;

 public class LinkedList<T> implements Iterable<T> {

   // Returns an iterator for this list
public Iterator<T> iterator() {
return new ListIterator(); // Create iterator of the inner class type
} // Default constructor - creates an empty list
public LinkedList() {} // Constructor to create a list containing one object
public LinkedList(T item) {
if(item != null) {
current = end = start = new ListItem(item); // item is the start and end
}
} // Construct a linked list from an array of objects
public LinkedList(T[] items) {
if(items != null) {
// Add the items to the list
for(int i = 0; i < items.length; ++i) {
addItem(items[i]);
}
current = start;
}
} // Add an item object to the list
public void addItem(T item) {
ListItem newEnd = new ListItem(item); // Create a new ListItem
if(start == null) { // Is the list empty?
start = end = newEnd; // Yes, so new element is start and end
} else { // No, so append new element
end.next = newEnd; // Set next variable for old end
end = newEnd; // Store new item as end
}
}
// Get the first object in the list
public T getFirst() {
current = start;
return start == null ? null : start.item;
} // Get the next object in the list
public T getNext() {
if(current != null) {
current = current.next; // Get the reference to the next item
}
return current == null ? null : current.item;
} private ListItem start = null; // First ListItem in the list
private ListItem end = null; // Last ListItem in the list
private ListItem current = null; // The current item for iterating private class ListItem { // Constructor
public ListItem(T item) {
this.item = item; // Store the item
next = null; // Set next as end point
} // Return class name & object
@Override
public String toString() {
return "ListItem " + item ;
} ListItem next; // Refers to next item in the list
T item; // The item for this ListItem
} private class ListIterator implements Iterator<T> {
// Constructor
public ListIterator() {
nextElement = getFirst();
} // Method to test whether more elements are available
public boolean hasNext() {
return nextElement != null;
} // Method to return the next available object from the linked list
public T next() {
T element = nextElement;
if(element == null) {
throw new java.util.NoSuchElementException();
}
nextElement = getNext();
return element;
} // Method to remove the last element retrieved from the linked list
// You don't want to support this operation for the linked list
// so just throw the exception
public void remove() {
throw new UnsupportedOperationException("Remove not supported for LinkedList<>");
} private T nextElement;
}
}

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

2、定义二叉树泛型类

 public class BinaryTree<T extends Comparable<T>> {

   // Add a value to the tree
public void add(T value) {
if(root == null) { // If there's no root node
root = new Node(value); // store it in the root
} else { // Otherwise...
add(value, root); // add it recursively
}
} // Recursive insertion of an object
private void add(T value, Node node) {
int comparison = node.obj.compareTo(value);
if(comparison == 0) { // If it is equal to the current node
++node.count; // just increment the count
return;
}
if(comparison > 0) { // If it's less than the current node
if(node.left == null) { // and the left child node is null
node.left = new Node(value); // Store it as the left child node
} else { // Otherwise...
add(value, node.left); // ... call add() again at the left node
}
} else { // It must be greater than the current node
if(node.right == null) { // so it must go to the right...
node.right = new Node(value); // store it as the right node
} else { // ...or when right node is not null
add(value, node.right); // ...call add() again at the right node
}
}
} // Create a list containing the values from the tree in sequence
public LinkedList<T> sort() {
LinkedList<T> values = new LinkedList<>(); // Create a linked list
treeSort(root, values); // Sort the objects into the list
return values;
} // Extract the tree nodes in sequence
private void treeSort(Node node, LinkedList<T> values) {
if(node != null) { // If the current node isn't null
treeSort(node.left, values); // process its left child node // List the duplicate objects for the current node
for(int i = 0 ; i < node.count ; ++i) {
values.addItem(node.obj);
}
treeSort(node.right, values); // Now process the right child node
}
} private Node root; // The root node // Private inner class defining nodes
private class Node {
Node(T value) {
obj = value;
count = 1;
} T obj; // Object stored in the node
int count; // Count of identical objects
Node left; // The left child node
Node right; // The right child node
}
}

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

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

 public class TryBinaryTree {
public static void main(String[] args) {
int[] numbers = new int[30];
for(int i = 0 ; i < numbers.length ; ++i) {
numbers[i] = (int)(1000.0*Math.random()); // Random integers 0 to 999
} // List starting integer values
int count = 0;
System.out.println("Original values are:");
for(int number : numbers) {
System.out.printf("%6d", number);
if(++count%6 == 0) {
System.out.println();
}
} // Create the tree and add the integers to it
BinaryTree<Integer> tree = new BinaryTree<>();
for(int number:numbers) {
tree.add(number);
} // Get sorted values
LinkedList<Integer> values = tree.sort();
count = 0;
System.out.println("\nSorted values are:");
for(Integer value : values) {
System.out.printf("%6d", value);
if(++count%6 == 0) {
System.out.println();
}
} // Create an array of words to be sorted
String[] words = {"vacillate", "procrastinate", "arboreal", "syzygy",
"xenocracy", "zygote" , "mephitic", "soporific",
"grisly" , "gristly" }; // List the words
System.out.println("\nOriginal word sequence:");
for(String word : words) {
System.out.printf("%-15s", word);
if(++count%5 == 0) {
System.out.println();
}
} // Create the tree and insert the words
BinaryTree<String> cache = new BinaryTree<>();
for(String word : words) {
cache.add(word);
} // Sort the words
LinkedList<String> sortedWords = cache.sort(); // List the sorted words
System.out.println("\nSorted word sequence:");
count = 0;
for(String word : sortedWords) {
System.out.printf("%-15s", word);
if(++count%5 == 0) {
System.out.println();
}
}
}
}

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

Java基础之泛型——使用二叉树进行排序(TryBinaryTree)的更多相关文章

  1. 黑马程序员:Java基础总结----泛型(高级)

    黑马程序员:Java基础总结 泛型(高级)   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 泛型(高级) 泛型是提供给javac编译器使用的,可以限定集合中的输入类型 ...

  2. Java基础总结--泛型总结

    -----泛型------JDK1.5出现的机制1.泛型出现的原因--简化书写,提高安全性技术的由来是为了解决问题,现在存在该问题,所有的容器定义类型为Object,所以任何对 象均可以放入容器--进 ...

  3. 黑马程序员——JAVA基础之泛型和通配符

    ------- android培训.java培训.期待与您交流! ---------- 泛型:            JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. 泛型好处: ...

  4. Java基础知识--泛型

    什么是泛型?为什么使用泛型? 泛型,就是参数化类型.提到参数,最熟悉的就是定义方法时候的形参,然后调用此方法时传递实参.顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也 ...

  5. Java基础知识强化58:经典排序之二叉树排序(BinaryTreeSort)

    1. 二叉树排序 二叉树排序的描述也是一个递归的描述, 所以二叉树排序的构造自然也用递归的: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它 ...

  6. 黑马程序员——【Java基础】——泛型、Utilities工具类、其他对象API

    ---------- android培训.java培训.期待与您交流! ---------- 一.泛型 (一)泛型概述 1.泛型:JDK1.5版本以后出现的新特性,用于解决安全问题,是一个类型安全机制 ...

  7. Java基础:泛型

    Java的泛型是什么呢, 就是类型的參数化,这得类型包含方法參数和返回值.也就是原本该是确定类型的地方换成了变量,把类型的确定时间向后延迟了. 在之前,学过"重载"的概念,重载是什 ...

  8. 【Java基础】泛型

    Num1:请不要在新代码中使用原生类型 泛型类和接口统称为泛型.每种泛型定义一组参数化的类型,构成格式是:类或接口名称,接着用<>把对应于泛型形式类型的参数的实际参数列表括起来.比如:Li ...

  9. java基础之 泛型

    泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法 ...

随机推荐

  1. json中含有Unicode的处理办法 C&num;

    public static class StringExtension { #region unicode 字符转义 /// <summary> /// 转换输入字符串中的任何转义字符.如 ...

  2. SQL Server 2008创建oracle链接服务器(心得)

    操作系统是32位的情况下,曾经没费太多时间创建好了到oracle的链接服务器.主要要点就是: 1.安装oracle精简客户端.当时我用的是版本比较低的“oracle9i310-客户端简化版”,安装好了 ...

  3. 转载:Objective-C中的 instancetype 和 id 关键字

    Objective-C中的instancetype和id关键字 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/16994 ...

  4. Java中线程池的学习

    线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...

  5. React学习笔记-04 props

    props实现从父组件与子组件的通信. 可以通过getDefaultProps初始化props. React 提供了propsTypes来验证props的类型 官方API: propTypes:fun ...

  6. 移动端与PHP服务端接口通信流程设计&lpar;增强版&rpar;

    增强地方一: 再增加2张表,一个接口表,一个授权表,设计参考如下: 接口表 字段名 字段类型 注释 api_id int 接口ID api_name varchar(120) 接口名,以"/ ...

  7. TensorRT下安装pycuda

    为了模型小型化,效率更高,使用TensorRT进行优化.前提是你必须要安装pycuda,可是费了我一番功夫.做一个笔记如下: 1.参考网址: https://wiki.tiker.net/PyCuda ...

  8. UIButton使用方法汇总

    //按钮初始化类方法 UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];//这里创建一个圆角矩形的按钮 //按 ...

  9. 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理&lbrack;附带源码分析&rsqb;

    前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...

  10. Linux基础语句总结

    看的视频是bilibili的网址如下:https://www.bilibili.com/video/av18069261/?p=36 然后做了点总结,可能有错误也可能有遗漏,同时参考了他人的资料. 系 ...