数据结构:线性表

线性表是基本的数据结构之一,是一组元素的抽象。

线性表包含顺序表和链接表(简称链表),顺序表在C语言中一般使用数组去实现,链表使用结构体去实现。在Python中,list对象是采用顺序表实现的。

1. 顺序表

顺序表是将表中的元素顺序的存储在连续的内存里。

优点:

  • 查询速度快,时间复杂度为O(1)

缺点:

  • 插入元素速度慢,时间复杂度为O(n)
  • 表中元素个数需要提前定义

2. 链表

链表:通过链接各个结点实现的技术就叫做链表。链表中的结点分为指针域和数据域,具体见下图。结点中的data用来存放数据,next用来存放下一个节点的地址。

链表分为单链表和双链表。单链表只有数据域data和地址域next指向下一个节点的地址,双链表含有前地址域prev、数据域data和后地址域next。

2.1 单链表

定义结点的代码:

# 定义结点  
class Node:  
    def __init__(self, data, next_=None):  
        self.data = data  
        self.next = next_
添加元素

  • 首先temp是遍历节点
  • 遍历结点使得temp指向最后一个结点
  • temp的地址域指向新添加的结点的地址
temp.next = node
插入元素

核心代码:
假如要在 元素10之间插入元素13,我们需要找到元素10的前一个元素,使得temp指向 元素9。

node = Node(13)  # node 是要插入的元素
node.next = temp.next
temp.next = node
删除元素

temp.next = temp.next.next

单链表实现全部代码:

  
# 定义结点  
class Node:  
    def __init__(self, data, next_=None):  
        self.data = data  
        self.next = next_  
  
class LinkedListUnderflow(ValueError):  
    pass  
  
# 头结点定义为空(头结点指向第一个元素)  
class single_linked_list:  
  
    def __init__(self):  
        self._head = None # 下划线开头,表明该成员变量是私有的  
 # 判断是否为空  
 def is_empty(self):  
        return self._head is None  
  
 # 开头插入  
 def prepend(self, data):  
        self._head = Node(data, self._head)  
  
    # 移除首元素,并返回该结点的data  
 def prepop(self):  
        if self.head is None:  
            raise LinkedListUnderflow("in prepop")  
        e = self._head.data  
        self._head = self._head.next  
        return e  
  
    # 移除尾部元素,并返回该结点的值  
 def pop(self):  
        if self._head is None:  
            raise LinkedListUnderflow("in pop")  
        temp = self._head  
        # 注意 temp 和 temp.next 的区别  
 while temp.next is not None:  
            temp = temp.next  
        e = temp.data  
        temp.next = None  
 return e  
# 该结点会自动被回收,如果是C语言需要手动free,释放节点的内存  
  
 # 尾部添加  
 def append(self, data):  
        if self._head is None:  
            self._head = Node(data)  
            return  
 # 遍历查找尾部结点  
 temp = self._head  
        while temp.next is not None:  
            temp = temp.next  
        temp.next = Node(data)  
        return  
  
 ''':找到满足给定条件的表元素, pred 是给定条件的函数  
 :只能找到第一个满足条件时的元素,pred 可以使用 lambda 表达式  
 ''' def find(self, pred):  
        temp = self._head  
        while temp is not None:  
            if pred(temp.data):  
                return temp.data  
            temp = temp.next  
        return  
 # 找到满足 pred 的所有 结点值  
 def filter(self, pred):  
        temp = self._head  
        while temp is not None:  
            if pred(temp.data):  
                yield temp.data  
            temp = temp.next  
        return  
  
 # 传统遍历  
 def print_all(self):  
        temp = self._head  
        while temp is not None:  
            print(temp.data, end='\t')  
            temp = temp.next  
        print()  
        pass  
  
 """:arg传统的遍历结点的所有值  
 这里使用谓词函数,调用的时候传入print函数即可  
 使用 C语言遍历时,可以直接把printf()函数写到函数里面  
 """ def for_each(self, proc):  
        temp = self._head  
        while temp is not None:  
            proc(temp.data, end='\t')  
            temp = temp.next  
        return  
  
 ''':遍历所有结点的data值:使用生成器函数定义迭代器  
 ''' def elements(self):  
        temp = self._head  
        while temp is not None:  
            yield temp.data       # 使用 yield 定义迭代器  
 temp = temp.next  
        return  
  
  
if __name__ == '__main__':  
    mlist = single_linked_list()  
    for i in range(10):  
        mlist.prepend(i)  
    for i in range(11, 20):  
        mlist.append(i)  
# 遍历输出所有元素  
 for x in mlist.elements():  
        print(x, end='\t')  
    print()  
      
    res = mlist.find(lambda x: x>15)  
    print(res)  
  
    for x in mlist.filter(lambda x: x>15):  
        print(x, end='\t')  
    print()  
  
    mlist.for_each(print)  
    print()  
    mlist.print_all()

2.2 双链表

正在总结中…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值