首页

对于集合实现序列List、类集Set及Map实现存储结构及算法遍历算法复杂度分析

标签:时间复杂度,集合,实现原理,数据结构,红黑树,性能对比     发布时间:2018-03-21   

一、前言

对于数据存储结构常见有:数组、单链表、双线链表、二叉树、多叉数、哈希表、红黑树等,其中红黑树可以自平衡二叉查找树,对于这几种数据结构的遍历查询速度性能,对比效率由小到大:O(1)<O(lgn)<O(n)< O(nlgn)<O(n2)< O(n3)<O(2n)<O(n!)<O(nn)(如下图,lgn对数)。

对于集合实现序列List、类集Set及Map实现存储结构及算法遍历算法复杂度分析

数组普通遍历=O(n)@b@数组二分查找遍历=二叉树=红黑树=O(lg2n)@b@多叉数=O(lgn)@b@哈希表=数组+红黑树/链表=HashMap=HashSet=O(nlgn)@b@数组两层嵌套遍历(两个for循环)=O(n2)@b@数组三层嵌套遍历(三个for循环)=O(n3)

二、集合对比

1.List - 序列(有序的集合,可重复)

ArrayList -> 数组 ->O(n)@b@    --get() 直接读取第几个下标,复杂度 O(1)@b@    --add(E) 添加元素,直接在后面添加,复杂度O(1)@b@    --add(index, E) 添加元素,在第几个元素后面插入,后面的元素需要向后移动,复杂度O(n)@b@    --remove()删除元素,后面的元素需要逐个移动,复杂度O(n)@b@LinkedList ->链表@b@    --get() 获取第几个元素,依次遍历,复杂度O(n)@b@    --add(E) 添加到末尾,复杂度O(1)@b@    --add(index, E) 添加第几个元素后,需要先查找到第几个元素,直接指针指向操作,复杂度O(n)@b@    --remove()删除元素,直接指针指向操作,复杂度O(1) @b@@b@对比分析:ArrayList 查询快,新增删除慢,LinkedList 相反@b@Vector --线程安全的ArrayList

2.Set-类集(不同类别集合,不可重复)

HashSet -> HashMap -> 数组++红黑树/链表->O(nlgn)@b@--不有顺序大小类集@b@TreeSet->二叉树->O(lg2n)@b@--有大小顺序、可排序的类集

3.Map-键值关系存储

HashMap->数组+红黑树/链表->O(nlgn)@b@--无插入顺序,非线程安全,根据HashCode决定存放数组位置@b@LinkedHashMap->数组+双向链表->O(nlgn)@b@--最近读取的数据放在最前面,最早读取的数据放在最后面,从而实现LRU缓存机制(最近最少使用)@b@TreeMap->红-黑二叉树->O(log n)@b@--默认键值的升序排序,非线程安全@b@注:Hashtable - 基于Dictionary类实现,线程安全,HashMap是其简单实现

三、时间复杂度 - 即 T(n) = O(f(n))

1、常数阶O(1)  -  无论代码执行了多少行,只要是没有循环等复杂结构(即使有几万几十万行),那这个代码的时间复杂度就都是O(1),如:

int i = 1;@b@int j = 2;@b@++i;@b@j++;@b@int m = i + j;

2、线性阶O(n)  - for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的,这类代码都可以用O(n)来表示

for(i=1; i<=n; ++i)@b@{@b@   j = i;@b@   j++;@b@}

3、对数阶O(logN) - 在while循环里面,每次都将 i 乘以 2,乘完之后,i 距离 n 就越来越近,也就是说 2 的 x 次方等于 n,那么 x = log2^n

int i = 1;@b@while(i<n)@b@{@b@    i = i * 2;@b@}

4、线性对数阶O(nlogN) - 将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN)

for(m=1; m<n; m++)@b@{@b@    i = 1;@b@    while(i<n)@b@    {@b@        i = i * 2;@b@    }@b@}

5、平方阶O(n²) - 把 O(n) 的代码再嵌套循环一遍,复杂度就是 O(n*n),即 O(n²)

for(x=1; i<=m; x++)@b@{@b@   for(i=1; i<=n; i++)@b@    {@b@       j = i;@b@       j++;@b@    }@b@}

6、立方阶O(n³) - 上面的O(n²) 去理解就好了,O(n³)相当于三层n循环