博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《数据结构》—— 线性表(上)
阅读量:5701 次
发布时间:2019-06-17

本文共 3220 字,大约阅读时间需要 10 分钟。

本文内容,参考自《大话数据结构》(程杰著) ,一部分自己修改,如:把C语言换成了Java语言。写作目的,意在加强记忆。

本文写作工具,使用 Typora ,Markdown 大法好。不过,和掘金提供的,有一些不兼容。

 1.线性表的定义

线性表(List):零个或多个数据元素的有限序列。

这里需要强调几个关键的地方。

首先它是一个序列。也就是说,元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后续,其他每个元素都有且只有一个前驱或后继。

然后,线性表强调是有限的,元素个数是有限的。事实上,在计算机中处理的对象都是有限的,那种无限的数列,只存在于数学的概念中。

若将线性表记为 (a1, … , ai-1,ai,ai+1, … ,an),则表中 ai-1 领先于 ai ,ai 领先于 ai+1 ,称 ai-1 是 ai 的直接前驱元素, ai+1 是 ai 的直接后继元素。当 i=1,2,…,n-1时,ai 有且仅有一个直接后继,当 i=2,3,…,n时,有且仅有一个直接前驱。

所以线性表元素的个数n(n ≧ 0)定义为线性表的长度,当 n=0 时,称为空表。

在非空表中的每个数据元素都有一个确定的位置,如 a1 是第一个数据元素,an 是最后一个数据元素, ai 是第 i 个数据元素,称 i 为数据元素 ai 在线性表中的位序。

比如,一年里的十二个月,是不是线性表呢?

当然是,1月开始,12月结束,当中的月份都有前驱和后继,而且一共只有十二个,完全符合线性表的定义。

2.线性表的顺序存储结构

我们来看看线性表的两种物理结构的第一种——顺序存储结构。

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

说白了,就是在内存中找了块地,通过占位的形式,把一定内存空间给占了,然后把相同数据类型的数据元素依次存放。线性表的每个数据元素,类型都相同,所以可以用数组来实现顺序存储结构,把第一个数据元素存到数组下标为 0 的位置,接着把线性表相邻的元素存储在数组中相邻的位置。

下面我们以数组实现的顺序存储结构,来说明一下,线性表顺序存储结构的读取、插入和删除。

public class Demo {​    private final int maxSize = 20;//存储空间初始化分配量    private int length;//当前长度    private int[] arr;//数组        public void Demo() {        this.arr = new int[maxSize];    }        //获取线性表的长度    public int length() {        return length;    }        //读取线性表第 index 个元素    public int get(int index) {        if(length==0 || index<0 || index>length-1) {            throw new IndexOutOfBoundsException();        }        int i = arr[index];        return i;    }      //存储元素    public void add(int item) {        if(length==maxSize) {            throw new IndexOutOfBoundsException();            //线性表已经满了        }        arr[length] = item;        length++;    }        //插入元素思路:    //如果插入的位置不合理,抛出异常    //如果线性表长度大于等于数组长度,则抛出异常或动态增加容量(可参考ArrayList源码)    //从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置    //将要插入元素填入位置i处    //表长加1    public boolean insert(int index,int key) {        if(length==maxSize) {            throw new IndexOutOfBoundsException();            //线性表已经满了        }        if(index<0 || index>length) {            throw new IndexOutOfBoundsException();            //index 不在范围内,这里是因为顺序存储结构,元素之间不能留空        }        if(index<=length-1) {            //插入的元素,不在表最后            //需要把插入位置之后的元素,向后移动一位            for(int k=length-1;k>=index;k--) {                arr[k+1] = arr[k];            }        }        arr[index] = key;        length++;                return true;    }        //删除元素思路:    //如果删除位置不合理,抛出异常    //从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置    //表长减1    public boolean delete(int index) {        if(length==0) {            throw new IndexOutOfBoundsException();//线性表为空        }        if(index<0 || index>length) {            throw new IndexOutOfBoundsException();            //index 不在范围内        }        if(index < length-1) {//不是删除最后的位置            for(int k=index;k < length-1;k++) {                arr[k-1] = arr[k];            }        }        length--;        return true;    }    }复制代码

根据上面的代码,可以得出:

线性表的顺序存储结构,在存、读数据时,不管是哪个位置,时间复杂度都是 O(1)。

而插入或删除时,如果元素要插入到最后一个位置,或者删除最后一个元素,此时时间复杂度为 O(1),因为不需要移动元素。如果元素要插入到第一个位置或删除第一个元素,那此时的时间复杂度为 O(n)。根据概率原理,每个位置插入或删除元素的可能性是相同的,也就说位置靠前,移动次数多,位置靠后,移动次数少。最终平均移动次数和最中间的那个元素的移动次数相等,为 (n-1)/2。根据大O阶推导方法,可以得出,平均时间复杂度为O(n)。

线性表顺序存储结构的优缺点

优点 缺点
无须为表示表中元素之间的逻辑关系而增加额外的存储空间 插入和删除操作需要移动大量元素
可以快速地存取表中任一位置的元素 当线性表长度变化较大时,难以确定存储空间的容量
造成存储空间的碎片

转载地址:http://pdvrt.baihongyu.com/

你可能感兴趣的文章
因为时间少
查看>>
leetcode 【 Best Time to Buy and Sell Stock II 】python 实现
查看>>
推荐15款创建漂亮幻灯片的 jQuery 插件
查看>>
【算法】CRF
查看>>
windows 8 微软拼音输入法
查看>>
Windows UI风格的设计(7)
查看>>
3. 指针的赋值
查看>>
linux小常识
查看>>
SQL中使用WITH AS提高性能 使用公用表表达式(CTE)简化嵌套SQL
查看>>
聊聊TaskExecutor的spring托管
查看>>
oracle 强行杀掉一个用户连接
查看>>
Git提交本地库代码到远程服务器的操作
查看>>
挨踢部落故事汇(13):扬长避短入行Oracle开发
查看>>
灾难拯救——让软件项目重回轨道
查看>>
ssh链接git服务器,解决push pull要求输入密码问题
查看>>
也说 Java 异常处理
查看>>
Netty 源码解析(二):对 Netty 中一些重要接口和类的介绍
查看>>
MAVEN spring boot 打包 和执行
查看>>
mysql中主外键关系
查看>>
第七章:数据字典
查看>>