顺序表是用一组地址连续的存储单元来保存数据的,所以它具有随机存取的特点。即查找快速,但是做插入或删除动作是,需要移动大量元素,效率较低。

    插入元素:将顺序表中原来第 i个元素及以后元素均后移一个位置,腾出一个空位置插入新元素,并且顺序表长度增1。

    删除元素:将顺序表中的第 i个元素以后的元素均向前移动一个位置,这样覆盖了原来的第 pos个元素,并且顺序表长度减1。

 

链表,是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。每个数据单元有两部分组成,一个是数据域,存储数据值;另一个是指针域,指向下一个数据单元。这样的数据单元叫做结点。当多个结点通过指针指向,关联起来,就形成了一个链,即链表。链表可分为单链表、双链表、循环链表。

 

单链表就是沿着单方向的链表。例如:A->B->C->... 只能顺序的连下去,即可以从A往下找其他元素,但是反之则不行。

    插入节点:假设要在单链表的a结点和b结点之间插入一个值为x的新结点。

                     首先让s的next指针指向b,即s->next = a->next;

                     然后,让a的next指针指向s,即a->next = s;

    删除结点: 首先,找到b结点前面的结点a。b的下一个结点就是a->next->next。

                     所以,只要让a的next指针跳过b结点,指向b的下一个结点就OK了,即a->next = a->next->next;

 

单链表只有一个指向下一结点的指针,也就是只能next

双链表除了有一个指向下一结点的指针外,还有一个指向前一结点的指针,可以通过prev()快速找到前一结点,顾名思义,单链表只能单向读取

所以双链表具有以下优点:

1、删除单链表中的某个结点时,一定要得到待删除结点的前驱,得到该前驱有两种方法,第一种方法是在定位待删除结点的同时一路保存当前结点的前驱。第二种方法是在定位到待删除结点之后,重新从单链表表头开始来定位前驱。尽管通常会采用方法一。但其实这两种方法的效率是一样的,指针的总的移动操作都会有2*i次。而如果用双向链表,则不需要定位前驱结点。因此指针总的移动操作为i次。

2、查找时也一样,我们可以借用二分法的思路,从中间节点开始前后同时查找,这样双链表的效率可以提高一倍。

 

可是为什么市场上单链表的使用多余双链表呢?

从存储结构来看,每个双链表的节点要比单链表的节点多一个指针,而长度为n就需要 n*length(这个指针的length在32位系统中是4字节,在64位系统中是8个字节) 的空间,这在一些追求时间效率不高应用下并不适应,因为它占用空间大于单链表所占用的空间;这时设计者就会采用以时间换空间的做法,这时一种工程总体上的衡量。

 

循环链表的特点是无须增加存储量,仅对表的链接方式稍作改变,即可使得表处理更加方便灵活。①循环链表中没有NULL指针。涉及遍历操作时,其终止条件就不再是像非循环链表那样判别p或p->next是否为空,而是判别它们是否等于某一指定指针,如头指针或尾指针等。 ②在单链表中,从一已知结点出发,只能访问到该结点及其后续结点,无法找到该结点之前的其它结点。而在单循环链表中,从任一结点出发都可访问到表中所有结点,这一优点使某些运算在单循环链表上易于实现。

posted on 2018-08-14 10:59  七调  阅读(159)  评论(0编辑  收藏  举报