`

算法与数据结构回顾--线性表(1)

阅读更多

既然叫回顾,当然不能仅仅介绍基础,这里主要解析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是判断)的元素。





分享到:
评论

相关推荐

    算法与数据结构:3-线性表2.pdf

    线性表是计算机科学中一种基础且重要的数据结构,它是由n(n≥0)个相同类型元素构成的有限序列,这些元素在逻辑上呈现线性顺序。在本篇文档中,我们将深入探讨线性表的链式存储结构,以及在C语言中如何使用指针和...

    数据结构和算法-思维导图.pdf

    以上是根据文件的标题、描述、标签和部分预览内容总结出的数据结构与算法知识点。这些知识点是IT行业中软件开发人员必备的基础知识,广泛应用于软件设计、算法实现、系统优化等众多领域。掌握这些知识点能够帮助IT...

    数据结构实验报告2线性表的链式存储结构.pdf

    随着信息技术的迅猛发展,数据结构作为计算机科学与技术专业核心课程之一,在教学和实践中的重要性日益凸显。本实验报告详细介绍了线性表的链式存储结构,通过编程实践深入理解了链表的逻辑结构、基本操作以及链表...

    C语言版数据结构与算法分析-严蔚敏经典视频教程

    01-001数据结构的概念和基本术语、抽象数据类型的表示与实现 01-002算法设计的要求、算法效率的度量 02-001线性表的类型定义 02-002线性表的顺序表示与实现、线性表的基本操作 02-003单链表的创建与操作、加工型...

    《数据结构与算法》课后习题答案

    在深入分析《数据结构与算法》课后习题答案之前,我们先回顾一下基础知识。数据结构是指计算机中组织和存储数据的方式,而算法则是解决特定问题的一系列指令或步骤。在计算机科学中,合理选择数据结构和高效算法对于...

    数据结构--C语言版

    - **第1章**:介绍数据结构和算法的基本概念,并回顾必要的数学知识和C#语言基础。这一章为读者提供了必要的背景知识,为后续深入学习打下坚实的基础。 - **第2章至第6章**:详细讨论了线性表、栈和队列、串和数组、...

    “数据结构与算法”课程学习总结报告

    基于这一重要性,本文将对“数据结构与算法”课程的学习进行总结,旨在梳理和回顾所学的核心内容,并对后续学习的侧重点提出建议。 课程伊始,我们首先对数据结构与算法的基础知识进行了回顾。数据是信息的载体,...

    数据结构与算法PPT

    数据结构与算法是计算机科学的基础,对于理解和设计高效的软件至关重要。这份"数据结构与算法PPT"提供了国外经典教材的详细讲解,旨在帮助学习者深入理解这一领域。以下是基于PPT文件名所涵盖的主要知识点: 1. **...

    中山大学本科数据结构教学课件

    《中山大学本科数据结构教学课件》是一份深入解析数据结构的教学资源,包含了丰富的理论知识与实践技巧。作为计算机科学的基础课程,数据结构对于理解算法的效率和优化编程至关重要。这份资料通过精炼的PPT形式和...

    数据结构与算法

    ### 数据结构与算法 #### 知识点一:数据结构概览 - **定义**:数据结构是指在计算机科学中,一组数据的存储结构。它不仅包括存储结构本身,还包括在此结构上的各种操作。 - **分类**:主要分为两大类: - **线性...

    小甲鱼_数据结构与算法(98集全)

    道01数据结构和算法绪论. mp402_谈谈算法. mp4 西03_时间复杂度和空间复杂度.mp404_时间复杂度和空间复杂度2.mp405_时间复杂度和空间复杂度3.mp4险06线性表. mp407_线性表2. mp408_线性表3. mp4品09_ 线性表4. mp...

    数据结构(Python语言描述)(微课版)-教案.pdf

    预习部分,学生需要掌握算法复杂度分析,复习Python中与算法和数据结构相关的内置库,如列表操作等。下一单元则将深入到线性表的其他变体,如有序表,这将引入排序和搜索等重要主题。 总的来说,这个教学单元旨在...

    计算机科学与工程领域——数据结构与算法的专著 C/C++数据结构算法

    本书在简要回顾了基本的C++程序设计概念的基础上,全面系统地介绍了队列、堆栈、树、图等基本数据结构,以及贪婪算法、分而治之算法、分枝定界算法等多种算法设计方法,为数据结构与算法的继续学习和研究奠定了一个...

    [BUPT]数据结构平时实验 源代码 + 实验报告整合资源包(计算机学院 - 大二上).zip

    线性表作为数据结构中最基础的模型之一,其包含的数组和链表是数据存储和管理中最常见的数据结构。在实验中,学生将通过设计图书管理系统来练习线性表的增删查等基本操作。这不仅要求学生熟练掌握线性表的使用,还要...

    数据结构(c#语言版)

    - **.NET框架中的数据结构与算法**:除了传统的数据结构与算法,本书还特别关注了.NET框架提供的内置数据结构和算法库,例如List、Dictionary, TValue&gt;等。 #### 五、配套资源与实践指导 **知识点解析** - **配套...

    数据结构(Python语言描述)(微课版)-教案.docx

    本课程的主要内容包括:数据结构的定义、分类和实现、线性表的定义、分类和实现、链式存储结构、单链表、双链表、静态链表等,以及算法的基本概念和术语、算法评价指标和算法复杂度等。 教学目的: 1. 了解数据...

    数据结构(C-#语言版)

    - **基础概念**:本书的第一章从数据结构和算法的基础概念入手,为读者提供了必要的理论准备,并简要回顾了相关的数学和C#基础知识。 - **常用数据结构**:第二章至第六章深入探讨了各种常用的数据结构,包括但不...

    2012级算法与数据结构实验指导书18.pdf

    在21世纪的科技浪潮中,算法与数据结构始终是计算机科学的基石。尤其对于立志在互联网领域深造的学子而言,掌握这些基本技能是立足未来技术竞争的关键。2012级算法与数据结构实验指导书,作为一门面向计算机大类学生...

Global site tag (gtag.js) - Google Analytics