从数组、链表到集合
来源:互联网 发布:php7性能会赶上java吗 编辑:程序博客网 时间:2024/06/05 14:59
一、数组
概念
使用连续的一块内存空间保存,长度在初始化时确定。
时间复杂度
访问第n个元素时,时间复杂度为O(1);当访问某个特定的元素时,时间复杂度为O(n);
怎么理解这两个时间复杂度不一致的情况,举个例子
String[]strings=newString[]{"1","2","3"}; System.out.println(strings[0]); for(Stringstr:strings){ if("1".equals(str)){ System.out.println("oyeah,findit!"); } }
查找:如上代码中,找到数组中的第一个元素,时间复杂度就是O(1);如果找到1这个字符串元素,则时间复杂度是O(n);
修改:如上代码,删除末尾一个元素,时间复杂度为O(1);如果删除的是第一个元素那么时间复杂度是O(n);
二、链表
1.单链表
概念
在非连续的单元保存数据,并且通过指针将各个内存单元链接在一起;存在一个头结点指向第一个节点,最后一个节点域指向null。
时间复杂度:访问第n个元素,时间复杂度为O(n);当修改第n个元素,时间复杂度为O(1);
怎么理解这个时间复杂度:
查找:如图,链表的结构为不连续的单元,每个元素单元之间通过指针进行连接。当需要访问第三个元素时,就需要首先从链表的头部开始查找,然后通过链表的指针找到第二个元素data1,同理找到第三个元素data2.当需要访问第n个元素时,这时候时间复杂度为O(n);
修改:如果删除第2个元素
第一步:断开第一个节点、第二个的后继节点
第二步:修改第一个节点的后继节点为第三个节点,
全部操作,时间复杂度为O(1);
2.循环链表
概念
从结构上来说,循环链表对于单链表来说;仅仅是在尾节点的指针域上多了一个指向头结点的指针域,而单链表是将尾节点的指针域置为null。
3.双链表
概念
在单链表的基础上,每个节点都存在一个前继节点与后继节点。
从而双向链表对于单链表来说,双链表的结构相比更为复杂;每个节点都存在一个前继节点的指针域和一个后继节点的指针域。
对比
1.查找
单链表仅仅存在一个后继节点的指针域,这就导致了用单向链表来茶盏数据时,只能向后查找;而双向链表则可以进行前后的遍历查找。
2.修改
单链表对于增加和修改来说,都只需要修改一个数据的后继节点的指针域;而双向链表有结构的原因,在修改某个节点的时候,在修改数据、后继节点的指针域的同时还需要修改一个前继节点的指针域。相比来说,双向链表的效率相比要差。
正因为在空间和结构上的复杂带来的查找的提升,往往在维护的时候需要更多成本。
3.对比一下数组和链表的区别
数组是在初始时由一段已经固定好的连续的内存的空间组成的结构;而链表则是动态的由一系列不连续的内存区域构成的结构。
4.数组和链表在java中的应用
常见集合类底层结构
HashMap\HashTable\ConcurrentHashMap\TreeMap
HashMap与HashTable都是由数组和链表为底层数据结构的一种集合类,从结构上来说算是一种链表的数组。由于数组与链表本身的数据结构,数组在删除和增加操作时效率相比链表底下,链表在查找时效率又比不得数组,至于原因在上面介绍数组和链表的数据结构时已经说明,这里不再赘述。而HashMap则是结合了数组的寻址快速,链表的删除和增加快速的特点。详解HashMap 请移步http://blog.csdn.net/vking_wang/article/details/14166593。
而对比HashMap和HashTable的源码,可以发现最大的不同就是HashTable在可能出现线程安全的操作或变量上都加上了synchronized修饰。这样在多线程操作的情况下,每个线程都需要来竞争操作对象的锁。保证了在同一时刻,共享对象资源的仅仅只有一个线程在操作。也正是因为如此,所以在单线程的情况下,HashTable比HashMap效率要差的多。
而在jdk1.5之后,新增了concurrent包之后,新增了一个map集合类 ConcurrentHashMap 。ConcurrentHashMap 在能保证多线程操作不出现线程安全的情况下,又能保证一定的效率。为什么说是一定的效率呢?因为在本质上ConcurrentHashMap也是使用锁来实现的,而有所不同的是ConcurrentHashMap在HashMap的基础上新增了一个Segment的概念。与HashMap类似ConcurrentHashMap也是通过取得key的hash值来将对应的value存放在不同的已经加了锁的Segment之中。 将锁的粒度控制在Segment级别。
TreeMap 底层的数据结构为红黑树,不在本次数组、链表的讨论之列。
TreeMap默认排序为ASCII排序,相比于HashMap的无固定顺序,还是TreeMap有它的特殊的地方。例如:在默写支付的调用接口中,还是需要使用到这个TreeMap。
TreeMap 默认是根据Key来进行排序,如果想通过value排序,需要通过Comparator接口来实现。
Map<String,String> map=new TreeMap<String,String>(); map.put("a","d"); map.put("b","c"); map.put("c","b"); map.put("d","a"); List<Map.Entry<String,String>> list = new ArrayList<>(map.entrySet()); Collections.sort(list,new Comparator<Map.Entry<String,String>>() { //降序排序 public int compare(Map.Entry<String, String> o1,Map.Entry<String, String> o2) { return o2.getValue().compareTo(o1.getValue()); } }); for(Map.Entry<String,String> mapping:list){ System.out.println(mapping.getKey()+":"+mapping.getValue()); }
参考资料:
HashMap http://blog.csdn.net/vking_wang/article/details/14166593
ConcurrentHashMap http://blog.csdn.net/sherry_rui/article/details/51462549
代码实现双向链表
http://benjaminwhx.com/2016/01/18/Java%E5%AE%9E%E7%8E%B0%E5%8D%95%E5%90%91%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90/
- 从数组、链表到集合
- 从对象数组到数组与集合
- EL表达式从数组 Map List集合取值
- Java_EL表达式从数组 Map List集合取值
- 数组集合
- 数组集合
- 集合(集合转成数组)
- 集合框架(一)续 向集合中添加一个集合、数组和List之间的相互转换、从集合中删除另一个集合所包含的元素
- 数组与集合 -- 数组
- iOS N个数组,从每个数组中取出一个元素,组合,成为一个新的数组的集合
- 从服务器获取数据(json数据,json集合数组数据)并解析
- 算法---从一个数组(或者集合中)找出和为某个值的下标
- 集合(Arrays)-数组变集合
- 随机从数组或集合中抽取一个值或 从list集合中随机抽几个值 或算权重
- 集合变数组---------集合变数组
- 用集合初始化数组
- 数组与集合
- 数组、集合排序
- Java Tips
- 三种遍历方式的区别
- 在浏览器的标签页显示网站标志图标(或指定图标)的方法
- NC portal 获取当前界面主表(子表)的值
- Android学习路线总结
- 从数组、链表到集合
- scrapy 把cookie并转化为字典的形式
- FLV文件格式详解
- 关于arraylist 的remove 与contain 方法
- css3中的writing-mode学习记录
- JavaScript最经典的55个技巧
- 关于苹果针对于 dynamic methods警告,被拒
- 常见排序算法java实现
- iOS/Android开发 联系方式18611907350