比较器二叉树

本文介绍了Java中的比较器Comparable接口及其在对象排序中的作用,详细讲解了二叉树作为排序数据结构的基础原理,并探讨了当类无法修改时如何使用Comparator接口进行排序。同时,文章对比了Comparable和Comparator的区别。

目录

1.1、常用比较器:Comparable

1.2、Binary Tree,二叉树

1.3、挽救的比较器

        如果现在要想为一组对象进行排序,那么必须有一个可以区分出对象大小的关系操作,而这个操作在Java之中就是利用比较器完成的。

1.1、常用比较器:Comparable

        如果要为对象指定比较规则,那么对象所在的类必须实现Comparable接口,下面首先来看一下这个接口的定义:

public interface Comparable<T> {
	public int compareTo(T o);
}

        根据文档的要求:要排序的数组所在的类一定要实现此接口,此接口返回的是int型数据,而用户覆写此方法的时候只需要返回三种结果:1(>0)、-1(<0)、0(=0)即可。

实现比较器

import java.util.Arrays;
class Person implements Comparable <Person> {
	private String name ;
	private int age ;
	public Person(String name,int age) {
		this.name = name ;
		this.age = age ;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]\n";
	}
	@Override
	public int compareTo(Person o) {
		if (this.age > o.age) {
			return 1;
		} else if (this.age < o.age) {
			return -1;
		} else {
			return 0;
		}
	}
}
public class TestDemo {
	public static void main(String[] args) throws Exception {
		Person per[] = new Person[] { new Person("张三", 20),
				new Person("李四", 19), new Person("王五", 21) };
		Arrays.sort(per) ;	// 排序
		System.out.println(Arrays.toString(per));
	}
}

以后不管是何种情况下,只要牵扯到对象数组排序的操作,永远都是比较器Comparable。

1.2、Binary Tree,二叉树

        二叉树是一种排序的基本的数据结构,而如果要想为多个对象进行排序,那么就必须可以区分出对象的大小,那么就必须依靠Comparable接口完成。

        二叉树的基本原理:取第一个元素作为根节点,之后每一个元素的排列要求:如果比根节点小的数据放在左子树,如果比根节点大的数据放在右子树,在输出的时候采用中序遍历(左-根-右)的方式完成。

        但是,不管是何种方式操作,一定要记住,这种数据结构的实现永远都需要依靠节点类,而这个时候的节点类要保存两个子节点:左、右。

class Student implements Comparable<Student> {
	private String name;
	private int age;
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]\n";
	}
	@Override
	public int compareTo(Student o) {
		if (this.age > o.age) {
			return -1;
		} else if (this.age < o.age) {
			return 1;
		} else {
			return 0;
		}
	}
}
class BinaryTree {
	@SuppressWarnings("rawtypes")
	private class Node {
		private Comparable data;
		private Node left;
		private Node right;
		public Node(Comparable data) {
			this.data = data;
		}
		@SuppressWarnings("unchecked")
		public void addNode(Node newNode) {
			if (this.data.compareTo(newNode.data) < 0) {
				if (this.left == null) { // 没有左子树
					this.left = newNode;
				} else {
					this.left.addNode(newNode);
				}
			} else {
				if (this.right == null) {
					this.right = newNode;
				} else {
					this.right.addNode(newNode);
				}
			}
		}
		public void printNode() {
			if (this.left != null) {
				this.left.printNode();
			}
			System.out.println(this.data);
			if (this.right != null) {
				this.right.printNode();
			}
		}
	}
	private Node root; // 根节点
	public void add(Student data) {
		if (data == null) {
			return;// 返回调用处
		}
		Node newNode = new Node(data); // 将数据封装为节点
		if (this.root == null) { // 没有根节点
			this.root = newNode;
		} else { // 保存到合适的位置
			this.root.addNode(newNode);
		}
	}
	public void print() {
		if (this.root != null) {
			this.root.printNode();
		}
	}
}
public class BinaryTreeDemo {
	public static void main(String[] args) {
		BinaryTree tree = new BinaryTree();
		tree.add(new Student("张三", 20));
		tree.add(new Student("李四", 19));
		tree.add(new Student("王五", 21));
		tree.print();
	}
}

        如果不是笔试之中出现,基本上就出现不了了,所以以上的代码,作为了解,清楚就行了,实际上也别用。

1.3、挽救的比较器

        之前使用的Comparable实际上是在一个类定义的时候就已经具备的功能了,但是如果说现在一个类已经定义完成了。

范例:已经定义好了一个Person类

class Person {
	private String name ;
	private int age ;
	public Person(String name,int age) {
		this.name = name ;
		this.age = age ;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]\n";
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
}

        这个类在设计之初并没有考虑到排序的要求,可是后来又需要进行排序,但是以上的类已经无法修改了,那么如何使用Arrays.sort()排序呢?为了解决这样的问题,在java里面又提供了另外一个比较器接口:java.util.Comparator接口,这个接口的定义如下:

public interface Comparator<T> {
	public int compare(T o1, T o2);
	public boolean equals(Object obj);
}

        在compare()方法上存在了两个参数用于比较大小,而要想使用这个接口,需要单独定义一个比较规则类。

范例:专门为Person类补救一个比较规则类

class PersonComparator implements Comparator<Person> {
	@Override
	public int compare(Person o1, Person o2) {
		if (o1.getAge() > o2.getAge()) {
			return 1;
		} else if (o1.getAge() < o2.getAge()) {
			return -1;
		} else {
			return 0;
		}
	}
}

        而后如果要进行排序的话,依然使用Arrays类的sort()方法:public static <T> void sort(T[] a, Comparator<? super T> c)

范例:实现排序

public class TestDemo {
	public static void main(String[] args) throws Exception {
		Person per[] = new Person[] { new Person("张三", 20),
				new Person("李四", 19), new Person("王五", 21) };
		Arrays.sort(per, new PersonComparator()); // 排序
		System.out.println(Arrays.toString(per));
	}
}

很明显,使用Comparator要比Comparable麻烦许多,所以以后别使它。

面试题:请解释Comparable和Comparator的区别?(请解释两种比较器的区别)

· java.lang.Comparable是在一个类定义的时候默认实现好的接口,里面只有一个compareTo()方法;

· java.util.Comparator是需要单独定义一个比较的规则类,里面有两个方法;compare()、equals()。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值