Python中的关联列表实现的实例教程

151 阅读4分钟

在计算机科学中,你可以用两种方式存储一个项目列表,要么在连续的内存位置,要么在随机的内存位置。

如果你将项目存储在连续的内存位置,如果我们知道第一个项目的内存位置,我们可以访问所有的项目。例如,数组或列表使用连续的内存位置来存储项目的列表。

链接列表是一种线性数据结构,其中的项目被存储在随机的内存位置。链接列表的每个内存位置被称为一个节点。这些节点用指针连接在一起。

由于项目处于随机位置,我们需要在当前节点中存储下一个项目的地址。因此,每个节点包含两个字段;一个是存储当前节点数据的数据值,一个是存储下一个节点地址的指针。

链接列表的最后一个节点包含一个指向NULL的指针。头部 是一个指针,保持对链表第一个元素的引用。

下面是一个链表的图示。这个链表有三个节点,其值为 A、B 和 C。

linked list example

链接表的例子

链表实现了空间的优化利用,因为节点可以位于内存的任何地方。另外,你不需要事先定义链表的大小,因为它是动态分配内存的。这些都是使用链表而不是数组的一些优点。

如果你还没有清楚地理解链接列表的工作,请看下面的视频。

使用 Python 实现链接列表

让我们用Python编程语言来实现链表。我们可以创建一个叫做Node的类,每当我们想在链接列表中添加一个节点时,我们可以创建这个类的一个对象。这个类将有两个属性:datanext

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

现在,让我们创建一个叫做LinkedList的类。我们可以创建这个类的一个对象来创建一个链接列表。这个类将有一个叫做head的属性,它可以作为一个指针使用。

class LinkedList:
  def __init__(self):
    self.head = None

插入节点

让我们创建一个链表,并使用 Python 在其中插入一些节点。你可以在链表的开头、链表的结尾或某个特定节点之后插入节点。我们将看到以这三种方式插入节点的 Python 代码。

在链表的开头插入

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

class LinkedList:
  def __init__(self):
    self.head = None

  def insertAtBeginning(self,new_value):
    new_node = Node(new_value)
    new_node.next = self.head
    self.head = new_node
    print("New node inserted with data",new_value)


lList = LinkedList()
lList.insertAtBeginning(5)
lList.insertAtBeginning(7)

linked list insert at the beginning

在链表的末端插入

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

class LinkedList:
  def __init__(self):
    self.head = None

  def insertAtEnd(self,new_value):
    new_node = Node(new_value)
    if self.head is None:
      self.head = new_node
      print("New node inserted with data",new_value)
      return  
    last_node = self.head
    while(last_node.next):
      last_node = last_node.next
    last_node.next = new_node
    print("New node inserted with data",new_value)


lList = LinkedList()
lList.insertAtEnd(2)
lList.insertAtEnd(4)

linked list insert at end

在一个特定的节点之后插入

我使用insertAtBeginning方法插入了一个节点,这样前面的节点就不会是空的。

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

class LinkedList:
  def __init__(self):
    self.head = None

  def insertAtBeginning(self,new_value):
    new_node = Node(new_value)
    new_node.next = self.head
    self.head = new_node
    print("New node inserted with data",new_value)

  def insertAfter(self,prev_node,new_value):
    if prev_node == None:
      print("Previous node is empty")
    new_node = Node(new_value)
    new_node.next = prev_node.next
    prev_node.next = new_node
    print("New node inserted with data",new_value)


lList = LinkedList()

lList.insertAtBeginning(5)

lList.insertAfter(lList.head,8)
lList.insertAfter(lList.head,3)

linked list insert after a specific node

遍历链表

在遍历中,我们访问链表的每个节点,对其进行一些操作,例如,打印每个节点中存在的数据。让我们看看如何打印链表中的所有数据值。

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

class LinkedList:
  def __init__(self):
    self.head = None

  def insertAtBeginning(self,new_value):
    new_node = Node(new_value)
    new_node.next = self.head
    self.head = new_node
    print("New node inserted with data",new_value)

  def printLinkedList(self):
    temp = self.head
    while(temp):
      print(temp.data)
      temp = temp.next


lList = LinkedList()

lList.insertAtBeginning(5)
lList.insertAtBeginning(1)
lList.insertAtBeginning(9)

lList.printLinkedList()

从链表中删除一个节点

让我们看看如何从链表中删除一个节点。这可以通过很多方式实现。但我们不打算尝试所有这些不同的方法。

在这里,我们将简单地创建一个接受一个值的方法,并删除包含该值的节点。

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

class LinkedList:
  def __init__(self):
    self.head = None

  def insertAtBeginning(self,new_value):
    new_node = Node(new_value)
    new_node.next = self.head
    self.head = new_node
    print("New node inserted with data",new_value)

  def printLinkedList(self):
    temp = self.head
    while(temp):
      print(temp.data)
      temp = temp.next

  def deleteNode(self,key):
    temp = self.head
    if(temp==None):
      print("Can't perform deletion")
      return
    while(temp != None):
      if(temp.data == key):
        break
      prev = temp
      temp = temp.next
    prev.next = temp.next
    temp = None
    print("1 node deleted with data",key)


lList = LinkedList()

lList.insertAtBeginning(5)
lList.insertAtBeginning(1)
lList.insertAtBeginning(9)

lList.deleteNode(1)

lList.printLinkedList()

linked list deletion

反转一个链表

让我们看看逆转一个链表的 Python 代码。

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

class LinkedList:
  def __init__(self):
    self.head = None

  def insertAtBeginning(self,new_value):
    new_node = Node(new_value)
    new_node.next = self.head
    self.head = new_node
    print("New node inserted with data",new_value)

  def printLinkedList(self):
    temp = self.head
    while(temp):
      print(temp.data)
      temp = temp.next

  def reverseLinkedList(self):
    prev = None
    curr = self.head
    while(curr is not None):
      next = curr.next
      curr.next = prev
      prev = curr
      curr = next
    self.head = prev
    print("LinkedList reversed")


lList = LinkedList()

lList.insertAtBeginning(5)
lList.insertAtBeginning(1)
lList.insertAtBeginning(9)

lList.printLinkedList()

lList.reverseLinkedList()

lList.printLinkedList()

reverse a linked list

删除一个链表

现在让我们试着写一个方法,当它被调用时删除整个链表。

class Node:
  def __init__(self,data):
    self.data = data
    self.next = None

class LinkedList:
  def __init__(self):
    self.head = None

  def insertAtBeginning(self,new_value):
    new_node = Node(new_value)
    new_node.next = self.head
    self.head = new_node
    print("New node inserted with data",new_value)
  
  def deleteLinkedList(self):
    curr = self.head
    while curr:
      temp = curr.next
      del curr.data
      curr = temp
    print("LinkedList deleted")


lList = LinkedList()

lList.insertAtBeginning(5)
lList.insertAtBeginning(1)
lList.insertAtBeginning(9)

lList.deleteLinkedList()

delete a linked list

我希望这篇文章对你有帮助。请查看我关于 Python 中队列堆栈数据结构的文章。