深入TreeMap和TreeSet集合
2016-09-09 11:11
190 查看
hashSet底层则实际是一个hashMap,而TreeSet底层则采用NavigableMap这个接口来保存TreeSet集合,而实际上NavigableMap只是一个接口,实际上面TreeSet还是用TreeMap来保存set元素.
TreeSet的初始化的时候都是初始化都是new 了一个TreeMap进行初始化;
TreeMap,它采用一种被称为“红黑树”的排序二叉树来保存Map中的的每个Entry---每个Entry都被当做一个红黑树的一个节点来对待;
TreeMap的插入就是一个“排序二叉树”算法;每当程序添加新节点时,总是从树的根节点开始比较,即将根节点当成当前节点,如果新增节点大于当前节点且当前节点的右节点存在,则以右节点作为当前节点;如果新增节点小于当前节点且当前节点的左节点存在,则以左节点作为当前节点;如果新增节点等于当前节点,则新增节点覆盖当前节点;直到某个节点的左右节点不存在,并结束循环;将新增的节点作为该节点的子节点,如果新增的节点大于该节点,则添加成该节点的右节点,如果新增的节点小于该节点,则添加成该节点的左节点;public V put(K key,V value){
Entry<K,V> t=root;
if(t==null){
root=new Entry<K,V>(key,value,null);
size=1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
Comparator<? super K> cpr=comparator;
if(cpr!=null){
do{
//使用parent 上次循环后的t所引用的Entry
parent=t;
//拿新插入的key和t的key进行比较
cmp=cpr.compare(key,t.key);
//如果新插入的key小于t的key,那么t等于t的左边的节点
if(cmp<0)
t=t.left;
//如果新插入的key大于t的key,那么t等于t的左边的节点
else if(cmp>0)
t=t.right;
else
return t.setValue(key);
}while(t!=null);
}
else{
if(key==null)
throw new NullPointException();
Comparator<? super K> k=(Comparable<? super K>) key;
do{
//使用parent 上次循环后的t所引用的Entry
parent=t;
//拿新插入的key和t的key进行比较
cmp=cpr.compare(key,t.key);
//如果新插入的key小于t的key,那么t等于t的左边的节点
if(cmp<0)
t=t.left;
//如果新插入的key大于t的key,那么t等于t的左边的节点
else if(cmp>0)
t=t.right;
else
return t.setValue(key);
}while(t!=null);
}
Entry<K,V> e=new Entry<K,V>(key,value,parent);
else parent.right=e;
public V get(Object key){
Entry<K,V> p=getEntry(key);
return(p==null?null:p.value);
}
comarator!=null则采用定制排序,<pre name="code" class="java">getEntryUsingComparator和<span style="font-family: Arial, Helvetica, sans-serif;">getEntry方法是相同的</span>
TreeSet的初始化的时候都是初始化都是new 了一个TreeMap进行初始化;
TreeMap,它采用一种被称为“红黑树”的排序二叉树来保存Map中的的每个Entry---每个Entry都被当做一个红黑树的一个节点来对待;
TreeMap的插入就是一个“排序二叉树”算法;每当程序添加新节点时,总是从树的根节点开始比较,即将根节点当成当前节点,如果新增节点大于当前节点且当前节点的右节点存在,则以右节点作为当前节点;如果新增节点小于当前节点且当前节点的左节点存在,则以左节点作为当前节点;如果新增节点等于当前节点,则新增节点覆盖当前节点;直到某个节点的左右节点不存在,并结束循环;将新增的节点作为该节点的子节点,如果新增的节点大于该节点,则添加成该节点的右节点,如果新增的节点小于该节点,则添加成该节点的左节点;public V put(K key,V value){
Entry<K,V> t=root;
if(t==null){
root=new Entry<K,V>(key,value,null);
size=1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
Comparator<? super K> cpr=comparator;
if(cpr!=null){
do{
//使用parent 上次循环后的t所引用的Entry
parent=t;
//拿新插入的key和t的key进行比较
cmp=cpr.compare(key,t.key);
//如果新插入的key小于t的key,那么t等于t的左边的节点
if(cmp<0)
t=t.left;
//如果新插入的key大于t的key,那么t等于t的左边的节点
else if(cmp>0)
t=t.right;
else
return t.setValue(key);
}while(t!=null);
}
else{
if(key==null)
throw new NullPointException();
Comparator<? super K> k=(Comparable<? super K>) key;
do{
//使用parent 上次循环后的t所引用的Entry
parent=t;
//拿新插入的key和t的key进行比较
cmp=cpr.compare(key,t.key);
//如果新插入的key小于t的key,那么t等于t的左边的节点
if(cmp<0)
t=t.left;
//如果新插入的key大于t的key,那么t等于t的左边的节点
else if(cmp>0)
t=t.right;
else
return t.setValue(key);
}while(t!=null);
}
Entry<K,V> e=new Entry<K,V>(key,value,parent);
//如果新插入的key小于parent的key,则e作为parent的左子节点 if(cmp<0) parent.left=e; <pre name="code" class="java"> //如果新插入的key大于parent的key,则e作为parent的右子节点
else parent.right=e;
//修复红黑树 fixAfterInsertion(e); size++; modCount++; return null; }TreeMap 根据Key来获取value;
public V get(Object key){
Entry<K,V> p=getEntry(key);
return(p==null?null:p.value);
}
final Entry<K,V> getEntry(Object key){ if(comarator!=null) //调用getEntryUsingComparator方法取出对应的key return getEntryUsingComparator(key); if(key==null) throw new NullPointerException(); //将key强制类型转换成Comparable实例 Comparable<? super K> k=(Comparable<? super K>) key; //从树的根节点开始 Entry<K,V> p=root; while(p!=null) { int cmp=k.compareTo(p.key); if(cmp<0) p=p.left; else if(cmp>0) p=p.right; else return p; } return null; }
comarator!=null则采用定制排序,<pre name="code" class="java">getEntryUsingComparator和<span style="font-family: Arial, Helvetica, sans-serif;">getEntry方法是相同的</span>
相关文章推荐
- Dubbo zookeeper 初探【转】
- iOS 后台定位审核被拒How to clarify the purpose of its use in the locatio
- Android invalidate() 、postinvalidate()和requestLayout()
- 给已经封装好的类,拓展新的方法
- Android面试——APP性能优化
- python中的configparser
- 使用xml实现studentCRUD的小案例
- Java 23 种设计模式
- MatCaffe的mex文件出现的问题
- 可逆矩阵的逆
- 不需要反编译查看APK信息,快速找出主入口包名类名
- REQUEST高级用法
- can总线和lin总线的区别与联系?
- cocos2d - JS 遮罩 ( ClippingNode )
- socket编程入门详解
- 加载界面读条
- HTML5新特性
- a的n次方的快速算法,N*N个位数是多少
- 进程间通信和线程间通信
- 各种排序算法复杂度、稳定性比较