数据结构与算法(四)线性表(2)

删除算法
删除算法的思路:
a).删除位置不合理,抛出异常;
b).取出删除元素,表长减1;
c).从删除元素开始,后面的每一个数据都向前移动一个位置;
程序:

在这里插入代码片

分析以上算法的时间复杂度:
a).若插入和删除数据刚好在最后一个位置,此时表内不需移动任何一个数据,此时时间复杂度为0(1);
b).若插入或者删除的数据刚好在第一个位置,此时后面的每一个元素都要发生移动,此时时间复杂度为0(n);
c).假设为平均情况,则时间复杂度为0((n-1)/2),简化后还是0(n);
结论:线性表的顺序存储结构,在存、储数据时,不管是哪个位置,时间复杂度都是0(1),在插入或者删除时,时间复杂度是0(n),所以线性表顺序存储结构适合元素比较稳定,不经常插入和删除元素,更多的是存取数据。
线性表顺序存储结构的优缺点:
优点:
a).不需要为表示表中元素间的逻辑关系而增加额外的存储空间;
b).可以快速地存取表中任意位置的元素;
缺点:
a).插入和删除操作需要移动大量的元素;
b).当线性表长度变化较大时,难以确定存储空间的容量;
c).容易造成存储空间的碎片(由于顺序存储结构申请存储空间时都是一块一块申请的,会产生两块之间的碎片空间,例如内存磁盘碎片清理);

针对线性表顺序存储结构的问题:在插入和删除时需要移动大量的元素,需要耗费大量时间,这是由于顺序存储结构中相邻两元素的存储位置也具有邻居关系,他们在内存中的位置是紧挨的,中间没有间隙,无法快速的插入和删除。
**解决方案:**在执行插入和删除任务时,由于不管在相邻元素中留下多少空间都是不能保证够,并且造成极大的空间浪费,如果可以用指针,即是每个元素多用一个位置来存放指向下一个元素位置的指针,这样通过地址就能快速找到相应的元素。
线性表的链式存储结构:
特点
a).用一组任意的存储单元存储线性表的数据元素,这组存储单元可以存在内存中未被占用的任意位置,例如第一个元素在A点,另一个元素存在离其很远的W点;
与顺序结构相比每一个数据元素只需要存储一个位置就可以,在链式存储结构中,除了要存储数据元素信息外,还要存储他的后继元素的存储地址(指针),所以在链式存储中,存一个数据需要用到两个位置空间,一个存元素,一个存地址。
b).存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素称为存储映像,也称为节点。
c).n个节点链接成一个链表,即为线性表(a1,a2,a3,an)的链式存储结构;
d).由于此链表中的每个节点只包含一个指针域,所以叫做单链表。
在这里插入图片描述
头指针:
a).头指针是指链表指向第一个节点的指针,若链表有头节点,则是指向头节点的指针;
b).头指针具有标识作用,所以常用头指针冠以链表的名字(指针变量的名字);
c).无论链表是否为空,头指针均不为空;
d).头指针是链表的必要元素;
头结点:
a).头结点是为了操作统一和方便而设立的,放在第一个元素的节点之前,其数据域一般无意义(也可以用来存放链表的长度);
b).有了头结点,对在第一元素节点前插入节点和删除第一节点起操作与其他节点的操作就可统一;
c).头结点不一定是链表的必要元素;

单链表图例:
在这里插入图片描述
空链表图例:
在这里插入图片描述
单链表的读取:
算法思路:
a).声明一个节点p指向链表第一个节点,初始化j从1开始;
b).当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个节点,j+1;
c).若到链表末尾p为空,则说明第i个元素不存在;
d).否则查找成功,返回节点p的数据;
由于算法的时间复杂度取决于i的位置,当i=1时,则不需要遍历,当i=n时,则要遍历n-1次才能,所以最坏的情况的时间复杂度为0(n);由于单链表结构中没有定义表长,所以不能实现知道要循环多少次,所以不方便用for来控制循环,算法的核心思想叫做“工作指针后移”,这其实也是很多算法的常用技术。
单链表的插入:
单链表第i个数据插入节点的算法思路;
a).声明一节点p指向链表头节点,初始化j从1开始;
b).当J<1时就遍历链表,让p的指针向后移,不断指向下一节点,j累加1;
c).若到链表末尾P为空,则说明第i个元素不存在;
d).否则检查成功,在系统中生成一个空节点s;
e).将数据元素e赋值给s->data;
f).s->next=p->next; p->next=s;
单链表的删除:
如图所示:
在这里插入图片描述
假设元素a2的节点为q,要实现节点q删除单链表的操作,其实就是讲它的前继节点的指针绕过指向后续节点就可:
p->next=p->next->next;或者
q=p->next;p->next=q->next;
单链表第i个数据删除节点的算法思路;
a).声明节点p指向链表的第一个节点,初始化j=1;
b).当j<1时,就遍历链表,让P的指针向后移动,不断指向下一个节点,j累加1;
c).若到链表末尾p为空,则说明第i个元素不存在;
e).否则查找成功,将欲要删除的节点p->next赋值给q;
f).单链表的删除语句:p->next=q->next;
g).将q节点中的数据赋值给e,作为返回;
h).释放q节点;
总结:
a).对于单链表插入和删除算法:它由两个部分组成;第一部分是遍历查找第i个元素,第二部分是事先插入和删除元素;
b).从整个算法来说,他们的时间复杂度都是0(n);这样如果不知道单链表中第i个元素的位置,那么单链表的时间复杂度就和顺序存储结构差不多。
c).如果我们希望从第i个位置开始,插入连续的100个数据,对于顺序存储结构来说,每一次插入都需要移动n-1个位置,每次都是0(n)。而单链表我们只需要在第一次时,找到第i个位置的指针,此时为0(n),接下来只是简单地通过赋值移动指针而已,时间复杂度为0(1);显然,对于插入或删除元素越频繁的操作,单链表的效率优势也就是越明显。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值