线性表--顺序表与链表

物理结构是逻辑结构在计算机中的存储形式
数据的存储结构中的顺序存储结构能正确反映数据元素之间的逻辑关系,而链式存储结构不能

线性表

(1、线性表是具有( 零个 )或 (多个 )数据元素的( 有限 )序列。

** 线性表中数据元素之间的关系是( 一对一 )的关系,即除了第一个和最后一个数据元素之外,其他数据元素都是( 首尾相连 )的**


(2、线性表的基本特征:

** 1、第一个数据元素没有前驱元素**

** 2、最后一个数据元素没有后继元素**

** 3、其余每个数据元素只有一个前驱元素和一个后继元素**

** 4、抽象数据类型**


(3、线性表一般包括( 插入 )、( 删除 )、( 查找 )等基本操作


(4、线性表按物理存储结构的不同可分为 顺序表(顺序存储) 和 链表(链式存储)

** 1、顺序表(存储结构连续)**

** 2、链表(存储结构上不连续,逻辑上连续)**


顺序表:

顺序表是在计算机内存中以( 一组地址连续 )的存储单元依次存储数据元素的线性结构。

顺序表效率分析:

顺序表插入和删除一个元素,最好情况下其时间复杂度(这个元素在最后一个位置)为O(1),最坏情况下其时间复杂度为O(n)

顺序表支持随机访问,读取一个元素的时间复杂度O(1)


顺序表的优缺点:

优点:支持随机访问

缺点:插入和删除操作需要移动大量的元素,造成存储空间的碎片。


顺序表适合元素个数变化不大,且更多是读取数据的场合。

Python中的 list 和 tuple 两种类型采用了顺序表的实现技术,具有前面讨论的顺序表的所有性质。


链表:

为什么需要链表:

(1、顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活。

(2、链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。


链表的定义:

链表是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)

顺序表存储数据信息 而链表存储下一个节点的位置( 地址 )


链表的分类:

1、 单向链表

2、单向循环链表

3、双向链表



单向链表:

单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域( 元素域,也就是存储的元素 )和一个链接域(存储的是节点,也就是地址)。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。


表元素域elem用来存放具体的数据。

链接域next用来存放下一个节点的位置

变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点




节点实现:
Class SingleNode(object):

   ‘’’单链表的节点’’’

   def __init__(self,item):

     \#item存放数据元素

     Self.item=item

     \#next是下一个节点的标识

     Self.next=None

 

单链表的典型操作

Is_empty() 链表是否为空

Length()链表长度

Travel()遍历整个链表

Add(item)链表头部添加元素

Append(item)链表尾部添加元素

Insert(pos,item)指定位置添加元素

Remove(item)删除节点

Search(item)查找结点是否存在
单向循环链表

单链表的一个变形时单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。



双向链表

一种更复杂的链表是“双向链表”或“双面链表”。

每个节点有两个链接:

1、 一个指向前一个节点,当此节点为第一个节点时,指向空值;

2、 而另一个指向下一个节点,当此节点为最后一个节点时,指向空值





链表失去了顺序表随机读取的优点,同时链表由于增加了节点的指针域,空间开销比较大,但对存储空间的使用要相对灵活。
链表与顺序表的各种操作复杂度如下所示: **

操作链表顺序表
访问元素O(n)O(1)
在头部插入/删除O(1)O(n)
在尾部插入/删除O(n)O(1)
在中间插入/删除O(n)O(n)
注意:

虽然“在中间插入/删除”表面看起来复杂度都是O(n),但是链表和顺序表在插入和删除时进行的是完全不同的操作。链表的 **主要耗时操作是遍历查找 **,删除和插入操作本身的复杂度是O(1).顺序表查找很快,主要耗时的操作是拷贝覆盖 。因为除了目标元素在尾部的特殊情况,顺序表进行插入和删除时需要对操作点之后的所有元素进行前后移位操作,只能通过拷贝和覆盖的方法进行。

链表的代码demo:
游标循环一次自动是下一个的值,跟next()差不多
例如
:
节点包含元素域和链接域

创建一个游标,指向头结点:
cur=self.__head
当游标指向位置不为空时:
while cur is not None:           #这里的cur意思是节点,若是cur.next代表的则是链接域里的值 ,  
	print(cur.item)
	移动游标
	cur=cur.next    #这里cur.next代表的意思是下一个节点,也就是cur=下一个节点
  
cur.item代表的是元素域  也就是元素值
cur.next代表的是链接域  也就是下一个元素值的地址 最后一个指向None

这里就是cur.next的用法

    def append(self, item):
        '''链表尾部添加元素'''
        # 创建新节点对象,将数据存储到新节点中
        node = Node(item)
        # 判断链表是否为空
        if self.is_empty():
            # 头部添加--将头结点指向node节点
            self.__head = node
        else:
            # 创建出cur游标,找到尾节点
            cur = self.__head
            # 移动游标,游标指向位置不为空时
            while cur.next is not None:
                # 移动游标
                cur = cur.next
            # 当循环结束之后,cur指向尾节点,此时将新的尾节点添加到旧的尾节点之后
            cur.next = node
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值