05=链表的原理与实现

Posted 伤心兮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了05=链表的原理与实现相关的知识,希望对你有一定的参考价值。

链表

一、链表

1.1 链表的概念

链表由一系列节点(链表中每一个元素称为节点)组成,节点在运行时动态生成 (malloc),每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域

对于链表,按结构可以分为单链表,其结构如下

循环链表,其结构如下

双向链表,其结构如下

  • 链表 vs. 数组

    • 在定义数组时,通常会给数组一个容量,但是如果在数组中,只有一个数据。其他空间就浪费了。链表就可以解决这种问题。注意的是链表不一定比数组节省空间
    • 链表不允许随机访问
动态数组单向链表双向链表
索引O(1)O(n)O(n)
尾插O(1)O(n)O(1)
头插O(n)O(1)O(1)
中间位置插入O(n)O(n)O(n)

1.2 操作

1.2.1 链表的创建

  • 链表是由链表节点一个个链接而成。
# 链表节点类  
class linknode:  
    def __init__(self, value=None, next=None):  
        self.value = value  # 数据  
        self.next = next    # 指针  
  
  
# 链表类  
class linklist:  
    def __init__(self):  
        self.head = linknode()      # 开始创建链表,为空  
        self.size = 0

1.2.2 头插

  • 链表头部插入元素步骤如下:
    1. 先创建一个值为value的节点linknode
    2. 然后将的node.next指向head.next
    3. 最后将head.next指向node

# 头插  
def add(self, value):  
    node = linknode(value)  
    node.next = self.head  
    self.head = node  
    self.size += 1

1.2.3 尾插

  • 链表尾部插入元素如下:
    1. 先创建一个值为 val 的链节点 node
    2. 使用指针 cur 指向链表的头节点 head
    3. 通过 cur.next 移动指针,从而遍历链表,直到 cur.next == None
    4. cur.next 指向将新的链节点 node

# 尾插  
def append(self, value):  
    node = linknode(value)  
    cur = self.head  
    while cur.next != None:  
        cur = cur.next  
    cur.next = node  
    self.size += 1

1.2.4 任意位置插入

  • 任意位置插入思路如下:
    1. 先创建一个值为 val 的链节点 node
    2. 使用指针 cur 指向链表的头节点 head
    3. 通过 cur.next 移动指针,从而遍历链表,到达想要插入位置的索引index-1
    4. 然后将node.next指向cur.next
    5. 最终将cur.next指向node

# 任意位置插入  
def insert(self, value, index):  
    assert 0 <= index <= self.size, '插入的位置超出界限'  
    assert self.head.next, '链表为空'  
    node = linknode(value)  
    cur = self.head  
    for i in range(index):  
        cur = cur.next  
    node.next = cur.next  
    cur.next = node  
    self.size += 1

1.2.5 从任意位置删除

  • 任意位置删除思路如下:
    1. 使用指针 cur 指向链表的头节点 head
    2. 通过 cur.next 移动指针,从而遍历链表,到达想要删除的位置索引index-1
    3. 直接将cur.next指向cur.next.next

# 任意位置删除  
def delete_index(self, index):  
    assert 0 <= index <= self.size, '删除的位置超出界限'  
    assert self.head.next, '链表为空'  
    cur = self.head  
    for i in range(index):  
        cur = cur.next  
    cur.next = cur.next.next  
    self.size -= 1

1.3 完整代码

  • 完整代码如下:
# 链表节点类  
class linknode:  
    def __init__(self, value=None, next=None):  
        self.value = value  # 数据  
        self.next = next    # 指针  
  
  
# 链表类  
class linklist:  
    def __init__(self):  
        self.head = linknode()      # 开始创建链表,为空。指向第一个链表元素  
        self.size = 0  
  
    # 计数  
    def counter(self):  
        print(f'链表元素个数为self.size')  
  
    # 显示链表中所有的元素  
    def show(self):  
        cur = self.head  
        print(f'链表中的元素为:', end=" ")  
        while cur.next != None:  
            cur = cur.next  
            print(f'cur.value', end=" ")  
  
    '''  
        从链表中插入元素  
    '''    # 头插  
    def add(self, value):  
        node = linknode(value)  
        node.next = self.head.next  
        self.head.next = node  
        self.size += 1  
  
    # 尾插  
    def append(self, value):  
        node = linknode(value)  
        cur = self.head  
        while cur.next != None:  
            cur = cur.next  
        cur.next = node  
        self.size += 1  
  
    # 任意位置插入  
    def insert(self, value, index):  
        assert 0 <= index <= self.size, '插入的位置超出界限'  
        assert self.head.next, '链表为空'  
        node = linknode(value)  
        cur = self.head  
        for i in range(index):  
            cur = cur.next  
        node.next = cur.next  
        cur.next = node  
        self.size += 1  
  
    """    
		从链表中删除元素      
	"""  
    # 任意位置删除  
    def delete_index(self, index):  
        assert 0 <= index <= self.size, '删除的位置超出界限'  
        assert self.head.next, '链表为空'  
        cur = self.head  
        for i in range(index):  
            cur = cur.next  
        cur.next = cur.next.next  
        self.size -= 1  
  
  
def main():  
    ll = linklist()  
    ll.add(14)          # 14  
    ll.add(13)          # 13 14  
    ll.append(5)        # 13 14 5  
    ll.append(20)       # 13 14 5 20  
    ll.insert(1, 2)     # 13 14 1 5 20  
    ll.delete_index(2)  # 13 14 5 20  
  
  
if __name__ == '__main__':  
    main()

1.4 参考文献

以上是关于05=链表的原理与实现的主要内容,如果未能解决你的问题,请参考以下文章

05-3_单链表的实现

数据结构:链表

双向链表的原理与实现

单链接表的实现之从尾部插入节点

数据结构 - 基于链表的队列

LRU 缓存淘汰算法