线性表、链式结构、单链表、循环链表、双向链表
线性表特性:
0个或多个元素的有限序列(数组),元素直接的关系为前驱后继,可以快速的存取任一位置的元素。
链式结构
单链表:
为解决插入和删除时需要移动大量元素。链式结构中,除了要存储元素信息外,还要存储后继元素的内存地址。存储元素信息的域又称为指针域,指针域中存储的信息称做指针或链,这两部分组成了元素ai的存储映射称为节点。n个结点链组成一个链表,即为线性表的链式存储结构,又因为链式结构中只包含一个指针,所以称为单链表。
第一个存储位置叫头指针。单链表第一个结点前附设一个结点称为头结点。
1.获得单链表第i个数据的算法思路:
1.声明一个结点first指向链表第一个结点,初始化j从1开始;
2.当j<i时,就遍历链表,让first的指针向后移动,不断指向下一结点,j累加1;
3.若到链表末尾P为空,则说明第i个元素不存在;
4.否则查找成功,返回结点P的数据。
2.单链表第i个数据插入结点的算法思路:
1.声明一结点P指向链表第一个结点,初始化j从1开始;
2.当j<i时,就遍历链表,让P的指针向后移动,不断指向下一结点,j累加1;
3.若到链表末尾P为空,则说明第i个元素不存在;
4.否则查找成功,在系统中生成一个空结点s;
5.将数据元素e赋值给s->data;
6.单链表的插入标准语句s->next=p->next; p->next=s;
7.返回成功。
3.单链表整表删除的算法思路如下:
1.声明一结点P和q;
2.将第一个结点赋值给P;
3.循环:
♦将下一结点赋值给q;
♦释放p;
♦将q赋值给p。
4.单链表整表创建的算法思路:
1.声明一结点P和计数器变量i;
2.初始化一空链表L;
3.让L的头结点的指针指向NULL,即建立一个带头结点的单链表;
4.循环:
♦生成一新结点赋值给P;
♦随机生成一数字赋值给P的数据域p->data;
♦将p插入到头结点与前一新结点之间。
总结
静态链表
静态链表对象结构:一个data存储对象、一个别用链表、另外有一个cur记录游标。
以单项链表为例,取消了定义顺序存储,所有的对象只需要在默认分配的内存空间内,解决了对象插入删除需要移动太多对象的缺点,但同时带来了链表长度难以确认,以及顺序结构随机存储的特性。
插入元素:调用malloc()方法申请空闲下标,如下图,获取头元素记录的空闲下标,同时还要把下一个空闲的下标8放入头元素的cur。当下一位置数据为空,cur用0表示。
从i前插入元素:其实意思就是,你花钱买了个一个i的位置站住,而原始i位置上的元素让你挤到了原本头元素中空闲的下标位置。
删除k元素:例如删除k位置的元素,调用free方法释放下标,把k的cur改为当前头元素中的cur,将k放入备用链表中,而k元素的下标要放入头元素中的cur。
个人理解:其实静态链表就是一个打乱顺序的单项链表,而每次删减元素不需要顺序移动元素。
循环链表
循环链表,见名识意是由单项链表改进的方案,在头节点、尾节点建立关系,尾部节点有指针指向头节点,从而使整个链表为一个闭环。任意一个节点可作为开始节点,来循环整个列表,终止条件为:判断循环的当前节点中下一指针是否为开始节点(避免死循环)。
双向链表
双向链表的对象结构有所变化,每个元素需要记录当前对象、上一节点(prior)指针和下一节点(next)指针。
在循环链表的基础上,为每个对象添加其上一元素所在位置,而头指针需要更换为尾部节点的指针。