408数据结构第二章

线性表

  • 定义和基本操作
    • 顺序表的定义和操作
      • 线性表的链式表示
        • 顺序表和链表的比较

定义和基本操作

线性表是具有相同数据类型的n个数据元素的有限序列
每个元素有且仅有一个直接前驱直接后继

线性表是一种逻辑结构,表示元素之间一对一的相邻关
顺序表和链表是指存储结构,两者属于不同层面的概念

LocateElem(L,e)按值查找,在表L中查找具有给定关键字的元素
GetElem(L,i)按位查找,获取表L中第i个位置的元素的值
PrintList(L)按前后顺序输出线性表L的所有元素值
Empty(L)若L为空表则返回true
DestroyList(&L)释放线性表内存空间

**&**表示C++语言的引用调用,对参数修改结果要带回来

顺序表的定义和操作

线性表的顺序存储又称顺序表
逻辑上相邻的两个元素在地理位置上也相邻
表中元素的逻辑顺序与其物理顺序相同
i为元素ai在线性表中的位序
sizeof(ElemType)存放的数据元素类型

线性表中元素的位序是从1开始,而数组中元素的下标是从0开始的
SqList顺序表的类型定义
ElemType*data指示动态分配数组的指针

动态分配并不是链式存储,同样属于顺序存储结构,物理结构没有变化,依然是随机存取方式,只是分配的空间大小可以在运行时动态决定

顺序表随机访问,通过首地址和元素序号可在时间O(1)内找到指定的元素
存储密度高每个结点只存储数据元素
插入和删除操作需要移动大量元素,不方便

C语言中,结构体中比较不能用“==”手写代码可以用不追求语言规则,除非特别指明

一个顺序表所占用的存储空间大小与元素的存放顺序无关
顺序表按序号随机存取

线性表的链式表示

单链表
线性表的链式存储又称单链表
通常用头指针来标识一个单链表
头指针都始终指向链表的第一个结点

头插法建立单链表的算法虽然简单,但生成的链表中结点的次序和输入数据的顺序不一致,一致则用尾插法
单链表的长度是不包括头结点的

双链表
双链表在单链表的结点中增加了一个指向其前驱的prior指针
可以很方便找到前驱结点,插入删除时间复杂度仅为O(1)

循环链表
循环单链表和单链表区别在于表中最后一个结点指针不是null,而改为指向头结点,从而形成环
任何一个位置上插入删除操作都是等价的,无须判断是否是表尾

循环双链表头结点的prior指针还要指向表尾结点

静态链表
借助数组来描述线性表的链式存储结构
插入删除只需要修改指针而不需要移动元素
没有单链表使用起来方便,不支持指针的高级语言

顺序表和链表的比较

1、存取方式
顺序表支持随机存取,而链表不支持,它只能从表头按顺序存取元素。

2、逻辑结构与存储结构
在顺序表中,逻辑上相邻的元素,其对应的物理位置也相邻,而链表中,逻辑上相邻的元素,其物理位置不一定相邻。

3、空间分配
在顺序表中,对于静态存储,一旦存储空间装满就不能扩充,再加入新元素将导致内存溢出;对于动态存储,存储空间装满时可以扩充,但需要移动大量元素导致效率降低,而且当内存中没有更大块的连续存储空间时导致内存分配失败。在链表中,对于静态存储,与顺序表的静态存储类似;对于动态存储,结点的空间只在需要的时候申请分配,只要内存有空间就可以分配成功。

4、存储密度
顺序表中,无论静态存储还是动态存储,其存储密度均为1,因为数组空间只用来存数据元素。而在链表中,对于静态存储和动态存储,每个结点除了存储数据元素自身外,还会至少存储直接后继的存储位置信息。相对于顺序表,链表的存储密度要低得多。

如何选取线性表的存储结构

1、基于存储规模的考虑
当线性表的长度或存储规模未知时,不宜采用顺序表,而应采用链表,因为链表不需要事先知道存储规模。

2、基于运算时间的考虑
如果需要进行大量的按序号访问操作,建议使用顺序表。在顺序表中,按序号访问元素的时间复杂度为O(1),而链表为O(n)。如果需要进行大量的插入、删除操作,建议使用链表。在顺序表中,插入、删除操作平均移动表中一半的元素,而链表则需要寻找插入或删除的位置,主要是在进行比较操作,其效率较高。

3、基于环境的考虑
顺序表容易实现,任何高级语言中都有数组类型;而链表是基于指针的,有些高级语言中没有指针类型,且一些操作的实现较为复杂

你可能感兴趣的:(算法,考研408,数据结构,链表)