慕课网liuyubobobo老师课程学习笔记---part1: chapter1(介绍)+chapter2(数组)

本文是关于数据结构学习的笔记,重点介绍了数据结构的基础概念,包括数据如何在计算机中组织和存储,以及数据结构的分类。接着深入探讨了数组,强调了数组的可遍历性及其在大O阶描述时间复杂度中的应用。文章还提到了均摊时间复杂度的概念,讨论了在考虑算法效率时如何防止复杂度的震荡,并提供了基于Java的动态数组实现。
摘要由CSDN通过智能技术生成

1、数据结构基础
  数据结构研究的是数据如何在计算机中进行组织和存储,使得我们可以高效的获取数据或者修改数据。
  数据结构的分类
在这里插入图片描述
  课程设置
在这里插入图片描述

2、数组
  数组之所以可以支持foreach的遍历,是因为数组具有 可遍历/可迭代 的能力。

1) 数组最大的优点:快速查询。scores[2]

2) 数组最好应用于“索引有语意”的情况,比如scores[2],就表示我们想要查询第二个人的成绩。但并非所有有语意的索引都适用于数组,身份证号:110103198512166666,如果设置为有语意的数组,开辟的空间太大造成浪费。数组也可以处理“索引没有语意”的情况,我们在这一章,主要处理“索引没有语意”的情况数组的使用。

3) 索引没有语意,如何表示没有元素?如何添加元素?如何删除元素?这些功能java数组(静态数组)并没有提供给我们,因此我们需要基于java的数组,二次封装属于我们自己的数组类(动态数组),添加这些功能。
大O阶描述时间复杂度

  大O描述的是算法的运行时间和输入数据之间的关系。对于循环结构代码,我们可以使用问题规模n与循环内O(1)复杂度的代码执行的次数来表示时间复杂度。既循环结构代码的时间复杂度可以通过复杂度为O(1)的代码执行次数随n的变化规律函数来计算。(具体参考《大话数据结构》以及视频)
  大O阶:渐进时间复杂度,描述n趋近于无穷的情况。
在这里插入图片描述
  数组便于修改和查找,不便于增加和删除。

均摊时间复杂度以及防止复杂度的震荡

  如果我们一直使用addLast()添加元素,它的时间复杂度为O(1),但是由于要修改容量resize(),resize()的时间复杂度为O(n),按照考虑最坏情况的规则,我们将时间复杂度算为O(n)。
  但是考虑到并不是每一次addLast()都要扩容,这种按照最坏情况考虑的方式不太合适。(见视频9-2.10分析)

	假设capacity=n,n+1次addLast,触发resize(执行n次元素赋值),总共进行2n+1次基本操作。平均,每次addLast操作,进行2次基本操作。平均,每次addLast操作,进行2次基本操作这样均摊计算,addLast()时间复杂度是O(1)的!
	在这个例子里,这样均摊计算,比计算最坏情况有意义,这是因为,最坏的情况不会每次都出现。这种计算复杂度的方法,称之为均摊复杂度。
	在实际工程过程中,y一个相对比较耗时的操作,如果我们可以保证它不会每次都触发,这个比较耗时的操作的时间可以分摊到其他的操作中。
	同理,我们看removeLast操作,均摊复杂度也为O(1)

  复杂度的震荡(视频9-6.10)。

	但是,当我们同时看addLast和removeLast操作,存在一种情况,每一次增加删除的操作都会耗费O(n)的复杂度,而实际上大部分情况下addLast和removeLast操作放入均摊复杂度都是O(1),这就是复杂度的震荡。
	出现问题的原因:removeLast 时 resize过于着急(Eager)。当我们既减少元素个数为数组容积的1/2的时候,我们马上把当前的容积缩容成为1/2O(n)),此时,我们数组中元素个数与容积是相等的,这种情况下,再添加一个元素就会马上进行O(n)复杂度的扩容。
	解决方案:lazy方式——我们增加元素容积不够用的时候,必然要进行O(n)的扩容,但是此时再删除一个元素,数组元素个数为容积的1/2,先不急着缩容,而是等到数组元素个数为容积的1/4的时候再进行缩容,而且只缩容为数组原先容量的1/2,此时数组还有一半的空间可以存储数据,再增加也不需要马上扩容。
	策略:当size==capacity/4时,才将capacity减半。

  我们自己创建一个新的数组,这个数据基于java给我们提供的数组的功能,封装了新的功能——添加,删除,查询,搜索、插入、使用泛型,动态数组(数组容量自动变化)等功能。代码如下:(测试见视频与项目ArrayTest)

package com.lkj;

public class Array<E>
{
   
    private E[] data;//数组容量capacity就是数组的length:data.length
    private int size;//数组中有效元素的个数

    //初始化数组的构造函数
    public Array(int capacity)
    {
   
        //初始化数组容量为capacity,数组中有效元素个数为0
//        data = new E[capacity];
        /**
         * 注意,java不支持直接:new E[capacity] 这样new一个E泛型类型的数组。
         * 我们必须先new一个Object类型的数组,然后再将其转换为E类型的数组
         */
        data = (E[])new Object[capacity];//注意,是转换为E类型的数组:E[] , 而不是转换为E类型
        size = 0;
    }

    // 无参数的构造函数,如果用户不指定,默认数组的容量capacity=10
    public Array
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值