既然叫回顾,当然不能仅仅介绍基础,这里主要解析java的线性表--List、map、set。
ArrayList
ArrayList的数据结构是由数组实现的,数组的初始化需要定义大小。所以使用ArrayList之前要估计List的大小。太小虽然不会出现溢出的异常,但是因为需要扩容所以浪费了很多资源,太大又浪费空间。
ArrayList初始化源代码:
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList() {
this(10);
}
扩容代码:
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
可见,ArrayList在容量不足时,就会通过复制数组的方式扩容。这种做法比较浪费资源。
这里的modCount是用来检测iterator操作不一致的,比如在迭代List的同时又修改List,这就是并发问题了,是不允许的。所以要及时抛出ConcurrentModifacationException.如下:
public static void main(String[] args){
List<String> strings = new ArrayList<String>();
for(int i=0;i<10;i++){
strings.add(String.valueOf(i));
}
Iterator it = strings.iterator();
for(int i=0;i < strings.size();i++){
System.out.println(it.next());
strings.remove(i);
}
}
检索代码:
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
可见检索的效率是非常高的,时间复杂度只为O(1)。但同时发现这个方法不是线程安全的,但同时相对于线程安全的方法,效率高一些。如果先要将ArrayList转换为线程安全的可以使用Collections.synchronizedCollection(strings)。 这个方法是用代理模式,将方法加锁。
删除代码:
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
添加代码和这个相差不多,这里就不多说了。这里面的删除时然被删除的元素后面的元素依次向左移动一位。所以时间复杂度是O(n)。同样线程不安全,不建议在删除多的操作上使用ArrayList。
LinkedList:
初始化:
Entry(E element, Entry<E> next, Entry<E> previous) {
this.element = element;
this.next = next;
this.previous = previous;
}
public LinkedList() {
header.next = header.previous = header;
}
从这个代码开来,LinkedList是一个环形双向链表。它有2个头指针一个指向一个指向链表的头部一个指向链表的尾部,这样它就可以找检索路径最短的那一段开始检索。代码如下:
private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Entry<E> e = header;
if (index < (size >> 1)) {
for (int i = 0; i <= index; i++)
e = e.next;
} else {
for (int i = size; i > index; i--)
e = e.previous;
}
return e;
}
这里使用了nb的位运算,它比正常的除以2运算效率要高。但是检索需要的时间是O(n).
添加:
public void add(int index, E element) {
addBefore(element, (index==size ? header : entry(index)));
}
private Entry<E> addBefore(E e, Entry<E> entry) {
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}
private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Entry<E> e = header;
if (index < (size >> 1)) {
for (int i = 0; i <= index; i++)
e = e.next;
} else {
for (int i = size; i > index; i--)
e = e.previous;
}
return e;
}
添加的时间复杂度是O(n).
删除:
public boolean remove(Object o) {
if (o==null) {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (e.element==null) {
remove(e);
return true;
}
}
} else {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (o.equals(e.element)) {
remove(e);
return true;
}
}
}
return false;
}
这里是根据value是不是null来分别区分,如果为null,就删除第一个为null的。如果不为null删除第一个相同(用equal是判断)的元素。
分享到:
相关推荐
线性表是计算机科学中一种基础且重要的数据结构,它是由n(n≥0)个相同类型元素构成的有限序列,这些元素在逻辑上呈现线性顺序。在本篇文档中,我们将深入探讨线性表的链式存储结构,以及在C语言中如何使用指针和...
以上是根据文件的标题、描述、标签和部分预览内容总结出的数据结构与算法知识点。这些知识点是IT行业中软件开发人员必备的基础知识,广泛应用于软件设计、算法实现、系统优化等众多领域。掌握这些知识点能够帮助IT...
随着信息技术的迅猛发展,数据结构作为计算机科学与技术专业核心课程之一,在教学和实践中的重要性日益凸显。本实验报告详细介绍了线性表的链式存储结构,通过编程实践深入理解了链表的逻辑结构、基本操作以及链表...
01-001数据结构的概念和基本术语、抽象数据类型的表示与实现 01-002算法设计的要求、算法效率的度量 02-001线性表的类型定义 02-002线性表的顺序表示与实现、线性表的基本操作 02-003单链表的创建与操作、加工型...
在深入分析《数据结构与算法》课后习题答案之前,我们先回顾一下基础知识。数据结构是指计算机中组织和存储数据的方式,而算法则是解决特定问题的一系列指令或步骤。在计算机科学中,合理选择数据结构和高效算法对于...
- **第1章**:介绍数据结构和算法的基本概念,并回顾必要的数学知识和C#语言基础。这一章为读者提供了必要的背景知识,为后续深入学习打下坚实的基础。 - **第2章至第6章**:详细讨论了线性表、栈和队列、串和数组、...
基于这一重要性,本文将对“数据结构与算法”课程的学习进行总结,旨在梳理和回顾所学的核心内容,并对后续学习的侧重点提出建议。 课程伊始,我们首先对数据结构与算法的基础知识进行了回顾。数据是信息的载体,...
数据结构与算法是计算机科学的基础,对于理解和设计高效的软件至关重要。这份"数据结构与算法PPT"提供了国外经典教材的详细讲解,旨在帮助学习者深入理解这一领域。以下是基于PPT文件名所涵盖的主要知识点: 1. **...
《中山大学本科数据结构教学课件》是一份深入解析数据结构的教学资源,包含了丰富的理论知识与实践技巧。作为计算机科学的基础课程,数据结构对于理解算法的效率和优化编程至关重要。这份资料通过精炼的PPT形式和...
### 数据结构与算法 #### 知识点一:数据结构概览 - **定义**:数据结构是指在计算机科学中,一组数据的存储结构。它不仅包括存储结构本身,还包括在此结构上的各种操作。 - **分类**:主要分为两大类: - **线性...
道01数据结构和算法绪论. mp402_谈谈算法. mp4 西03_时间复杂度和空间复杂度.mp404_时间复杂度和空间复杂度2.mp405_时间复杂度和空间复杂度3.mp4险06线性表. mp407_线性表2. mp408_线性表3. mp4品09_ 线性表4. mp...
预习部分,学生需要掌握算法复杂度分析,复习Python中与算法和数据结构相关的内置库,如列表操作等。下一单元则将深入到线性表的其他变体,如有序表,这将引入排序和搜索等重要主题。 总的来说,这个教学单元旨在...
本书在简要回顾了基本的C++程序设计概念的基础上,全面系统地介绍了队列、堆栈、树、图等基本数据结构,以及贪婪算法、分而治之算法、分枝定界算法等多种算法设计方法,为数据结构与算法的继续学习和研究奠定了一个...
线性表作为数据结构中最基础的模型之一,其包含的数组和链表是数据存储和管理中最常见的数据结构。在实验中,学生将通过设计图书管理系统来练习线性表的增删查等基本操作。这不仅要求学生熟练掌握线性表的使用,还要...
- **.NET框架中的数据结构与算法**:除了传统的数据结构与算法,本书还特别关注了.NET框架提供的内置数据结构和算法库,例如List、Dictionary, TValue>等。 #### 五、配套资源与实践指导 **知识点解析** - **配套...
本课程的主要内容包括:数据结构的定义、分类和实现、线性表的定义、分类和实现、链式存储结构、单链表、双链表、静态链表等,以及算法的基本概念和术语、算法评价指标和算法复杂度等。 教学目的: 1. 了解数据...
- **基础概念**:本书的第一章从数据结构和算法的基础概念入手,为读者提供了必要的理论准备,并简要回顾了相关的数学和C#基础知识。 - **常用数据结构**:第二章至第六章深入探讨了各种常用的数据结构,包括但不...
在21世纪的科技浪潮中,算法与数据结构始终是计算机科学的基石。尤其对于立志在互联网领域深造的学子而言,掌握这些基本技能是立足未来技术竞争的关键。2012级算法与数据结构实验指导书,作为一门面向计算机大类学生...