知识要点:
1、线性结构的特点、线性表的定义,线性表的基本操作;
2、线性表的顺序存储结构,对其进行检索、插入和删除等操作;
3、线性表的链式存储结构,单链表、双向链表和循环链表这三种链表形式的存储结构和特点以及基本操作。
线性表的定义:具有相同数据类型的数据元素的有限序列;
线性表中元素的个数为线性表的长度,当数据元素个数为0时该表为空表。
有且只有一个被称为“第一个”的数据元素;
有且只有一个被称为“最后一个”的数据元素;
除第一个元素外每一个元素都有唯一的前驱元素;
除最后一个元素外每一个元素都有唯一的后继;
线性表的存储结构(顺序存取):支持顺序和随机存取
特点:采用一组连续的地址空间,数据元素逻辑上相邻物理上也相邻。
Loc(a[i])=Loc(a[1])+(i-1)*L; //地址之间的关系
查找:顺序查找 时间复杂度O(n);平均查找长度:(n+1)/2
随机查找 时间复杂度O(1);
插入:时间复杂度O(n);平均移动次数:n/2
有效位置:【1,n+1】
删除:时间复杂度O(n);平均移动次数:(n-1)/2
有效位置:【1,n】
线性表的存储结构(链式存取):支持顺序存取
特点:添加一个指针位保存后继结点的位置;结点包含指针域和数据域两部分。
查找:时间复杂度O(n);平均查找长度:(n-1)/2
插入:未知插入位置 时间复杂度O(n);已知插入位置 O(1);
删除:未知删除位置 时间复杂度O(n);已知删除位置 O(1);
首元结点和头结点:首元结点第一个保存数据的结点、头结点使后序操作(查找、插入、删除)一致;
单链表创建方式:头插法和尾插法。
头插法:始终在链表的头部添加数据结点
1、创建结点 p; 2、在头部插入结点、p->next=head->next,head->next=p;
尾插法:始终在链表的尾部插入数据结点
1、创建结点p; 2、在尾部插入结点、p->next=NULL,head->next=p,head=p;
单链表:包含两部分指针域、数据域
初始化:head->next=NULL;
判空标志:head->next=NULL;是否存在链表标志:head=NULL;
双向链表:包含三部分 前驱指针域、数据域、后继指针域
初始化:head->next=NULL;head->pre=NULL;//前后指针域为空
判空标志:head->next=NULL;是否存在链表标志:head=NULL;
插入操作:已知p结点和q结点,在两者之间插入新结点s
s->next=q;q->pre=s;p->next=s;s->pre=p;
已知p结点,在后面插入s结点
s->next=p->next;p->next->pre=s;p->next=s;s->pre=p;
总结:先构建新的连接,在进行原来结点指针的修改
循环单链表:包含两部分指针域、数据域
初始化:head-next=head;//后继指针域指向自身
判空标志:head->next=NULL;是否存在链表标志:head=NULL;
插入操作:同单链表
循环双向链表:包含三部分 前驱指针域、数据域、后继指针域
初始化:head-next=head;head->pre=head;//前后指针域都指向自身
判空标志:head-next=head;head->pre=head;是否存在链表标志:head=NULL;
插入操作:同双向链表
静态链表(非链表):借助数组来表示链式关系,包括两部分数据域和指针域,需要预先分配内存空间
数组下标为0的位置开始一次根据next中所对应的部分找寻下一个结点,最后一个位置next位置为-1;(a->b->c)
下标 | data | next |
0 | 2 | |
1 | b | 3 |
2 | a | 1 |
3 | c | -1 |
重点:顺序表和链表的比较(没有绝对好的方式,两者各有优缺点)
1、存储分配
顺序表存储空间要预先分配,元素扩充收到限制,易造成空间溢出和浪费现象;
链表不需要预先分配存储空间,元素可扩充;
顺序表逻辑上相邻的元素物理上也相邻;顺序表逻辑上相邻的元素物理上未必相邻,但对每个结点内部地址是连续的;
2、存储密度:存储元素占用的存储量/实际所开辟的存储空间
顺序表存储密度理想情况下为1;链表存储密度小于1(存储密度不大);
3、时间性能(主要针对插入、删除操作)
顺序表支持随机存取,时间复杂度为O(1),链表只支持顺序存取时间复杂度为O(n);
对于插入和删除操作若不知道具体位置两者的时间复杂度都为O(n);在已知位置的情况下链表的时间复杂度为O(n);
顺序表的时间复杂度为O(n);