数据结构----线性表

一、线性表:零个或多个数据元素的有限序列。
线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,称为空表

1、线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。(可用一维数组实现)
属性:存储空间的起始位置,线性表的最大存储容量,线性表的当前长度
时间复杂度为O(1)的存储结构成为随机存取结构。

2、插入算法的思路:
如果插入位置不合理,抛出异常;
如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;
从最后一个元素开始向前遍历到第i个位置,分别将他们都向后移动一个位置;
将要插入元素填入位置i处;
表长+1;

3、删除算法的思路:
如果删除位置不合理,抛出异常;
取出删除元素;
从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置;
表长-1;

4、线性表顺序结构总结:
线性表的顺序存储结构,在存、读数据时,时间复杂度都是O(1);而插入或删除时,时间复杂度都是O(n);
优点:
无须为表示表中元素之间的逻辑关系而增加额外的存储空间
可以快速地存取表中任一位置的元素
缺点:
插入和删除操作需要移动大量元素
当线性表长度变化较大时,难以确定存储空间的容量
造成存储空间的”碎片“

5、线性表的链式存储结构
为了表示每个数据元素与其直接猴急数据元素之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称做指针或链。这两部分信息组成数据元素ai的存储映像,称为结点
因为此链表的每个结点中只包含一个指针域,所以叫做单链表。链表中第一个结点的存储位置叫做头指针。线性链表的最后一个结点指针为”空“(通常用NULL表示)。
为了更加方便地对链表进行操作,会在单链表中的第一个结点前附设一个结点,称为头结点

typedef struct PolyNode *Polynomial;
typedef struct PolyNode {
int coef;
int expon;
Polynomial link;
}

6、头结点与头指针的异同
头指针:头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针;头指针具有标识作用,所以常用头指针冠以链表的名字;无论链表是否为空,头指针均不为空。头指针是链表的必要元素。
头结点:头结点是为了操作的统一和方便而设立的,放在第一元素的结点之前,其数据域一般无意义(也可存放链表的长度);有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其他结点的操作就统一了;头结点不一定是链表必须要素。

7、若线性表为空表,则头结点的指针域为”空“。

8、获得链表第i个数据的算法思路:
声明一个结点p指向链表第一个结点,初始化j从1开始;
当j小于i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
若到链表末尾p为空,则说明第i个元素不存在;
否则查找成功,返回结点p的数据。
O(n)
核心思想是”工作指针后移“

9、单链表的插入:
s->next=p->next; p->next=s;
就是让p的后继结点改成s的后继结点,再把结点s变成p的后继结点。

10、单链表第i个数据插入结点的算法思路:
声明一个结点p指向链表第一个结点,初始化j从1开始;
当j小于i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
若到链表末尾p为空,则说明第i个元素不存在;
否则查找成功,在系统中生成一个空节点s;
将数据元素e赋值给s->data;
单链表的插入标准语句s->next=p->next; p->next = s;
返回成功;

11、单链表的删除
q=p->next; p->next =q->next;
让p的后继的后继结点改成p的后继结点。

12、单链表第i个数据删除结点的算法思路:
声明一个结点p指向链表第一个结点,初始化j从1开始;
当j小于i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
若到链表末尾p为空,则说明第i个元素不存在;
否则查找成功,将欲删除的结点p->next赋值给q;
单链表的删除标准语句: p->next =q->next;
将q结点中的数据赋值给e,作为返回;
释放q结点;
返回成功。

13、对于插入或删除数据越频繁的操作,单链表的效率优势就越是明显。

14、单链表整表创建的算法思路:
声明一结点p和计数器变量i;
初始化一空链表L;
让L的头结点的指针指向NULL,即建立一个带头结点的单链表;
循环:
{生成一新结点赋值给p;
随机生成一数字赋值给p的数据域p->data;
将p插入到头结点与前一新结点之间。}
这段算法始终让新结点在第一的位置,称为头插法

15、单链表整表删除的算法思路:
声明一结点p和q;
将第一个结点赋值给p;
循环:
{将下一结点赋值给q;
释放p;
将q赋值给p;}

16、单链表结构和顺序存储结构异同:
存储分配方式:
顺序存储结构用一段连续的存储单元依次存储线性表的数据元素;
单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。
时间性能:
查找:顺序存储结构O(1),单链表O(n);
插入和删除:顺序存储结构需要平均移动表长一半的元素,时间为O(n);单链表在查找出某位置的指针后,插入和删除时间仅为O(1)。
空间性能:
顺序存储结构需要预分配存储空间,分大了浪费,分小了容易发生上溢;单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。

17、静态链表:用数组描述的链表
未被使用的数组元素称为备用链表,而数组第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素的cur就存放第一个有数值的元素的下标,相当于单链表中的头结点作用;

18、静态链表优缺点:
优点:在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点。
缺点:没有解决连续存储分配带来的表长难以确定的问题;失去了顺序存储结构随机存取的特性

19、将单链表中终端节点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表

20、终端结点用尾指针rear表示。
合并两个链表:
p=rearA->next;
rearA->next = rearB->next->next;
rearB->next=p;
free(p);

21、双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱。
p->next->prior = p = p->prior->next;
插入操作:
s ->prior=p;
s->next=p->next;
p->next->prior=s;
p->next=s;
删除:
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);

22、线性表基本操作:
数组:




23、链表:





24、广义表

猜你喜欢

转载自blog.csdn.net/qq_38224589/article/details/81568025