数据结构---TreeSet简单实现

TreeSet简介

TreeSet是无序的集合容器,但也有排序的规则,元素实现Comparable接口,使其具有排序能力, TreeSet按照排序规则,进行排序,也通过这个接口实现元素唯一性;TreeSet不像HashSet,HashSet需要重写hashCode()和equals()方法,保证数据唯一性,hashSet底层存储结构是hash表,TreeSet是二叉树;

源码分析

TreeSet代码分析
1. TreeSet调用add方法,存储元素
2. 底层调用方法如下
在这里插入图片描述
put()方法时TreeMap的方法,存贮采用二叉树形式。当返回值为null时,表示将数据存储成功了,如果么有则返回的是以前的原始集合。
在这里插入图片描述

  1. 如果集合为空,第一次呢存储元素,则进行一下元素与null的比较

在这里插入图片描述

  1. 如果集合中传入比较器,则通过比较器比较,采用二叉树的中序遍历
    在这里插入图片描述
    这是集合中不存在这个对象,新建对象,保存到集合中。关于存放位置,如果返回值小于0,存放在二叉树的左边,否则存在在二叉树的右边。

在这里插入图片描述

采用接口Comparable接口中的方法,原理相同。
在这里插入图片描述

注意:
比较过程底层是中序遍历,遍历过程是采用前序遍历。

自定义TreeSet实现

package eTree.treeSetPack;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import eTree.Node;

/**
 * 自定义TreeSet
 *
 * @author mahao
 * @date: 2019年3月22日 下午9:31:28
 * @param <E>
 *            实现Comparable接口的类
 */
public class TreeSet<E extends Comparable<E>> implements Iterable<E> {

	Node<E> root;

	public E add(E e) {
		Node<E> node = new Node(e, null);
		if (root == null) {
			root = node;
			return null;
		} else {
			return work(root, e);
		}
	}

	private E work(Node<E> node, E e) {
		E n = (E) node.data;
		int flag = e.compareTo(n);
		if (flag > 0) {
			if (node.right == null) {
				node.right = new Node<>(e, null);
				return null;
			}
			return work(node.right, e);
		} else if (flag < 0) {
			if (node.left == null) {
				node.left = new Node<>(e, null);
				return null;
			}
			return work(node.left, e);
		} else {
			// System.out.println("数据相同,舍弃---数据相同");
			E oldE = (E) node.data;
			node.data = e;
			return oldE;
		}

	}

	@Override
	public Iterator<E> iterator() {
		return new Iter();
	}

	// 中序遍历
	private class Iter implements Iterator<E> {

		List<E> list = null;
		int i = 0;

		public Iter() {
			list = new ArrayList<E>();
			work(list, root);
		}

		private void work(List list, Node node) {
			if (node != null) {
				work(list, node.left);
				list.add(node.data);
				work(list, node.right);
			}
		}

		@Override
		public boolean hasNext() {
			return !(i == list.size());
		}

		@Override
		public E next() {
			return list.get(i++);
		}
	}

}

//添加元素

package eTree.treeSetPack;

/**
 * TreeSet中存储的对象,按照年龄降序排序, 如果年龄相同,判断名字是否相同
 *
 * @author mahao
 * @date: 2019年3月3日 上午11:48:56
 */
public class User implements Comparable<User> {

	private String name;
	private int age;
	private String str;

	@Override
	/**
	 * 实现compareTo方法,使具有排序的能力 1 - 当前对象大 0 - 两对象相等 -1 - 被计较对象大;
	 */
	public int compareTo(User o) {
		if (null == o)
			throw new NullPointerException();
		System.out.println("比较过程--" + this.name + "--compareTo--" + o.getName());
		int num = this.age - o.getAge();
		if (num == 0)// 年龄相同时,比较姓名是否一样,字符串默认实现了Comparable接口
			return this.name.compareTo(o.getName());
		return num;
	}

	public User(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public User(String name, int age, String str) {
		this.name = name;
		this.age = age;
		this.str = str;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getStr() {
		return str;
	}

	public void setStr(String str) {
		this.str = str;
	}

}

//测试

package eTree.treeSetPack;

import java.util.Iterator;

/**
 * 二叉树
 *
 * @author mahao
 * @date: 2019年3月22日 下午6:47:37
 */
public class MainClass2 {

	public static void main(String[] args) {

		TreeSet<User> set = new TreeSet<User>();
		set.add(new User("11", 5,"flag--11"));
		set.add(new User("16", 1,"flag--16"));
		set.add(new User("11", 7,"flag--11"));
		set.add(new User("14", 1,"flag--14"));
		set.add(new User("16", 1,"flag--18"));
		Iterator<User> it = set.iterator();
		while(it.hasNext()) {
			User u = it.next();
			System.out.println(u.getName()+"---"+u.getAge()+"-----"+u.getStr());
		}
	}
}

结果--------

比较过程--16--compareTo--11
比较过程--11--compareTo--11
比较过程--14--compareTo--11
比较过程--14--compareTo--16
比较过程--16--compareTo--11
比较过程--16--compareTo--16
14---1-----flag--14
16---1-----flag--18
11---5-----flag--11
11---7-----flag--11

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值