1-数据结构 - 链表

about

链表是由一系列节点组成的元素集合。

链表又分为:

  • 单向链表。
  • 双向链表。
  • 环形链表。

线性表

无论是列表还是链表都可以抽象地称其为线性表。一个线性表是某类元素的集合,它还记录着元素之间的顺序关系,线性表是最基本的数据结构之一,应用十分广泛,根据其存储方式不同,又分为:

  • 顺序表(列表),将元素顺序的存储在一块连续的存储空间中,元素间的顺序关系由它们的存储顺序自然表示。
  • 链表,各个元素分布在不同的存储空间中,它们之间的关系通过"链"连起来。

单向链表

单向链表也叫做单链表,是链表中最简单的一种形式,它每个节点包含两部分:

  • 数据域(item),也叫做信息域、元素域,存数据用的。
  • 链接域,指向下一个节点的指针next,而最后一个节点的next指向一个空值。

通过节点间的相互连接,最终串联成一个链表。

链表通常有一个头节点,如下图的a1,通过头节点可以找到后续的任意节点。当然,你也可以称an为尾节点。

class Node(object):
    """ 节点 """
    def __init__(self, item):
        self.item = item  # 元素
        self.next = None  # 初始节点的next为None

class SingleNode:
    """ 单链表的节点 """
    def __init__(self, item):
        self.item = item  # 元素
        self.next = None  # 初始节点的next为None

链表的操作

创建链表有两种方法:

  • 头插法。
  • 尾插法。

顾名思义,一个从头插入,一个从尾部插入。

class Node:
    def __init__(self, item):
        self.item = item
        self.next = None  # 初始节点的next节点为None


class OperatorLinkList(object):
    """ 单向链表的操作 """

    def create_link_list_head(self, li):
        """ 头插法,这里可以不管tail,因为tail一直不变 """
        head = Node(li[0])  # 将列表下标为0的元素当作head
        for element in li[1:]:  # 因为下标为0的元素已经被当作头节点了,所以这里从下标1开始循环
            node = Node(element)  # 创建新的节点
            node.next = head  # 将新节点的next指向上个节点
            head = node  # 然后将head指向新节点
        return head  # 返回链表的head,可以通过head找到链表中的所有节点

    def create_link_list_tail(self, li):
        """ 尾插法,这里可以不管head,因为head一直不变 """
        head = Node(li[0])  # 将列表下标为0的元素当作head
        tail = head  # 刚开始,尾巴和head都指向头节点
        for element in li[1:]:
            node = Node(element)  # 创建新的节点
            tail.next = node  # 让当前节点的next指向新节点
            tail = node  # 让tail也指向新节点
        return head  # 返回链表的head,可以通过head找到链表中的所有节点

    def get_link_list(self, head):
        """ 通过head获取链表的所有节点 """
        while head:  # 当head.next不为None,就循环输出
            print(head.item, end=' ')
            head = head.next
        print()

    def insert_node(self, head, key, element):
        """ 插入,head是链表的头部,key表示插入的位置,element插入的元素 """
        p = Node(element)
        while head:
            if head.item == key:
                p.next = head.next
                head.next = p
            head = head.next  # 用于循环,从head挨个往后找,直到遇到None

    def remove_node(self, head, element):
        """ 删除节点,head是链表的头部,element是要删除的元素 """
        while head:
            # 如果当前元素的下一个节点值等于element,那就让当前节点next指向下一个节点的下一个节点
            if head.next.item == element:
                head.next = head.next.next
                break
            head = head.next
        else:
            print('删除的元素[{}]不存在'.format(element))


lk = OperatorLinkList()
h = lk.create_link_list_head([1, 2, 3])  # 头插法创建单向链表
t = lk.create_link_list_tail([1, 2, 3])  # 尾插法创建单向链表
lk.get_link_list(t)
lk.insert_node(t, 1, 4)
lk.get_link_list(h)
lk.get_link_list(t)
lk.remove_node(t, 2)
lk.get_link_list(t)
posted @ 2017-12-19 15:30  听雨危楼  阅读(190)  评论(0编辑  收藏  举报