您的位置:首页 > 理论基础 > 数据结构算法

《大话数据结构》学习笔记--chapter 3

2017-07-06 23:32 369 查看

chap 3     线性表

3.2 线性表的定义

       线性表(list):零个或多个数据元素的有限序列;
l  前驱元素:
l  后继元素:
l  线性表的长度:线性表中元素的个数n;
l  空表:n=0时;
复杂的线性表中,一个数据元素可以有若干个数据项组成;(表格)
 

3.3 线性表的抽象数据类型(操作)

建立、清空、获得长度、查找等等;
 

3.4 线性表的顺序储存结构

3.4.1 定义:用一段地址连续的存储单元依次存储线性表的数据元素;

3.4.2 顺序存储方式:一维数组;

3.4.3 数据长度与线性表长度的区别:

       数组的长度:是存放线性表的存储空间的长度,存储空间分配后这个量一般是不变的;
       线性表的长度:线性表中元素的个数,随着线性表插入和删除操作的进行而变化;
       线性表的长度小于等于数组的长度;

3.4.4 地址计算方法:

       分配的数组的空间要大于等于当前线性表的长度;
       地址:每个储存单元的自己的编号称为地址;
 

3.5 顺序储存结构的插入与删除

 

3.5.1 获得元素操作:

3.5.2 插入操作:

l  插入位置不合理,抛出异常;
l  线性表长度大于等于数组长度,抛出异常或动态增加容量;
l  从最后一个开始遍历到第i个位置,分别将他们向后移动一个位置;
l  将要插入的元素填入位置i处;表长加1;
***JAVA 中的插入方法是:void add ( intindex, Integer element);

3.5.3 删除操作:

l  删除位置不合理,抛出异常;
l  取出删除元素;
l  从删除位置开始遍历到最后一个元素,分别将他们都向前移动一个位置;
l  表长减1;
***线性表的顺序储存结构,读取、存储的时间复杂度是O(1),插入、删除的时间复杂度是O(n),所以比较适合元素个数变化不大,更多的是存储数据的应用;

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

       优点:逻辑关系不用耗费额外的存储空间;
                     可以快速的存取表中任一位置的元素;
       缺点:插入和删除需要移动大量元素;
                     线性表长度变化较大时,难以确定储存空间的容量;
                     造成储存空间的“碎片”;
 

3.6 线性表的链式储存结构

3.6.1 顺序储存结构不足的解决办法:

       给前边的元素添加后边元素的内存地址索引值

3.6.2 线性表链式存储结构定义:

l  用任意存储单元存储线性表的数据元素,可以连续,可以不连续
l  链式结构中,要存储数据元素信息+后继元素的存储地址;
l  数据域+指针域,指针中存储的信息称为指针或链;这两部分信息组成数据元素a的存储映像,称为结点(Node);
l  N个结点连接成一个链表,即为线性表的链式存储结构;(单链表)
l  链表中的第一个结点的存储位置叫做头指针
l  单链表的第一个结点前附设一个结点叫头结点,头结点的数据域不存储信息,最后一个结点的指针指向空(null);

3.6.3 头指针和头结点的异同:

l  头指针
n  头指针是链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针;
n  头指针具有标识作用,常用头指针冠以链表的名字;
n  无论链表是否为空,头指针不能为空;
l  头结点
n  放在第一元素的结点前,其数据域一般无意义,可用来存放链表的长度;
n  方便对第一元素结点前的数据插入,和第一结点的删除;
n  头结点不是链表必须的;

3.6.4 线性链式储存结构的代码描述:

       结点由存放数据元素的数据域和存放后继结点地址的指针域组成;
       For instance:
假设p是指向线性表第i个元素的指针,该结点的数据域可以用p->data来表示,值为一个数据元素;指针域可以用p->next表示,值为一个指针,指向第i+1个元素;
 

3.7 单链表的读取

       查找链表第i个数据的算法思路:(其实就是顺序查找)
l  声明一个指针p指向链表的第一个结点,初始化j从1开始;
l  当j小于i时,遍历链表,p依次向后移动,j累加1;
l  若一直查询到链表结尾还没有找到,则说明第i个结点不存在;
l  否则查找成功,返回结点数据;
核心思想就是,工作指针后移,最坏情况的时间复杂度是O(n);
 

3.8 单链表的插入

       将元素e插入到结点p和p->next之间的算法思路:
l  生成一个新的结点s;
l  将元素e赋值给s->data;
l  将p的后继结点改成s的后继结点,再把s变成p的后继结点;即
S->next =p->next; p->next = s;(注意两句不能颠倒)
 

3.8 单链表的删除

       将结点o, p, q 中的p结点删除的算法思路:
l  o->next =p->next,即令o->next = q;
l  释放p结点,
 

3.9 单链表的创建

       单链表和顺序储存结构不同,是一种动态结构,所占空间的大小和位置不需要预先划分,可以根据系统的情况和实际的需求即时生成;
       创建单链表的过程是一个动态生成链表的过程,从“空表”的初始状态起,一次建立各个元素结点,并逐个插入链表;
       算法思路:
l  声明一个指针p和计数器变量i;
l  初始化一个空链表L;
l  让L的头结点指针指向NULL,即建立一个带头结点的单链表;
l  循环
n  生成一个新节点赋值给p;
n  随机生成一个数字赋值给p的数据域p->data;
n  将p插入到头结点与前一新结点之间;
**这种方法叫--头插法:始终让新结点在第一的位置;
**另一种尾插法:让新节点插在终结点的后面;
 

3.10 单链表的整表删除

       即将这个链表在内存中释放掉;
       算法思路:
l  声明一个结点p和q;
l  将第一个结点赋值给p;
l  循环:
n  将下一个结点赋值给q;
n  释放p;
n  将q赋值给p;
***注意q的必要性,起到指引下一个删除的元素的作用;
 

3.11 单链表结构与顺序存储结构优缺点

l  存储分配方式:
n  顺序储存结构用一段连续的存储单元依次存储线性表的数据元素;
n  单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素;
l  时间性能:
n  查找:O(1)和O(n)
n  插入和删除:O(n)和O(1);
l  空间性能:
n  顺序存储空间需要预分配存储空间;可能造成空间浪费和溢出;
n  单链表不需要分配存储空间,元素个数不受限制;
l  结论:
n  频繁查找,宜采用顺序储存结构;
n  频繁插入和删除,宜采用单链表结构;
n  在预知元素个数的时候,采用顺序存储结构;反之则使用单链表;
 

3.12 静态链表:

       某些语言在没有指针的情况下,让数组的每个数据元素由两个数据域组成,data和cur,数据域data,用来存放数据元素,cur相当于单链表中的next指针,存放该元素的后继在数组中的下表,cur叫游标;这种用数组描述的链表叫做静态链表;
       第一个元素和最后一个元素做特殊处理,不存数据。把未被使用的数组元素称为备用链表。第一个元素的cur游标存放备用链表的第一个结点的下标;最后一个元素的cur存放第一个有值元素的下标,相当于单链表的头结点;
 

3.12.1 静态链表的插入操作:

       把要插入的新结点存储在备用链表中(由未被使用过的和已经被删除的分量用游标连接成),改变插入位置前后元素的cur值即可;

3.12.2 静态链表的删除操作:

       让删除的位置成为第一个优先空位,把他存入第一个元素的cur中;

3.12.3 静态链表的优缺点:

优点:插入和删除时,不需要移动大量元素,只需修改游标;
缺点:表长难以确定;不能随机存取;
 

3.13 循环链表:

       将单链表中终端结点的指针由空指针改为指向头结点;
 

3.14 双向链表:

       在单链表的每个结点中,都设置一个指向其前驱结点的指针域;(即一共两个指针域,一个指向后继,一个指向前驱);
       插入和删除时,需要更改两个指针变量;
l  插入操作:把s插入到p和p->next之间:
       S->prior = p;
       s->next = p->next;
       p->next ->prior = s;
       p->next = s;
l  删除操作:删除p->prior和p->next之间的p:
P->prior->next= p->next;
p->next->prior= p->prior;
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: