当前位置:   article > 正文

Python中的链表和数组如何区分?

Python中的链表和数组如何区分?

链表是节点的集合。第一个节点(Node)一般被称为Head。最后一个节点的Next属性必须指向 None ,表明是链表的结尾。

在大多数编程语言中,链表和数组在内存中的存储方式存在明显差异。数组要求内存空间是连续的,链表可以不连续。

然而,在 Python 中,list是动态数组。所以在Python中列表和链表的内存使用非常相似。

链表和数组在以下的操作中也有本质区别:

1.插入元素:数组中插入元素时,插入位置之后的所有元素都需要往后移动一位,所以数组中插入元素最坏时间复杂度是 O(n)链表可以达到 O(1) 的时间复杂度。

2. 删除元素:数组需要将删除位置之后的元素全部往前移动一位,最坏时间复杂度是 O(n),链表可以达到 O(1) 的时间复杂度。

3.随机访问元素:数组可以通过下标直接访问元素,时间复杂度为O(1)。链表需要从头结点开始遍历,时间复杂度为O(n)。

4.获取长度: 数组获取长度的时间复杂度为O(1),链表获取长度也只能从头开始遍历,时间复杂度为O(n)。
实现链表

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

在LinkedList中,需要存储的唯一信息是链表的开始位置(链表的头部)。接下来,创建另一个类Node来表示链表的每个节点:

  1. class Node:
  2. def __init__(self, data):
  3. self.data = data
  4. self.next = None

我们可以给刚创建的两个类添加 __repr__ 方法, 在创建实例的时候输出更多有用的信息:

  1. class LinkedList:
  2. def __init__(self):
  3. self.head = None
  4. def __repr__(self):
  5. node = self.head
  6. nodes = []
  7. while node is not None:
  8. nodes.append(node.data)
  9. node = node.next
  10. nodes.append("None")
  11. return " -> ".join(nodes)

我们可以给刚创建的两个类添加 __repr__ 方法, 在创建实例的时候输出更多有用的信息

  1. class Node:
  2. def __init__(self, data):
  3. self.data = data
  4. self.next = None
  5. def __repr__(self):
  6. return self.data

创建测试类, 测试上面的代码

  1. from LinkedList import LinkedList
  2. from Node import Node
  3. if __name__ == '__main__':
  4. llist = LinkedList()
  5. print(llist)
  6. first_node = Node('a')
  7. llist.head = first_node
  8. print(llist)
  9. second_node = Node('b')
  10. third_node = Node('c')
  11. first_node.next = second_node
  12. second_node.next = third_node
  13. print(llist)

修改__init__ 方法,可以传入列表快速创建LinkedList

  1. def __init__(self, nodes=None):
  2. self.head = None
  3. if nodes is not None:
  4. node = Node(data=nodes.pop(0))
  5. self.head = node
  6. for elem in nodes:
  7. node.next = Node(data=elem)
  8. node = node.next

创建__iter__ 方法,遍历链表

  1. def __iter__(self):
  2. node = self.head
  3. while node is not None:
  4. yield node
  5. node = node.next
  1. from LinkedList import LinkedList
  2. if __name__ == '__main__':
  3. llist = LinkedList(['a','b','c','d','e'])
  4. print(llist)
  5. for node in llist:
  6. print(node)

实现链表,添加节点

在头部添加Node:在链表的开头添加一个Node,不必遍历链表,只需将新的Node的next属性指向 self.head ,并将新的node设置为新的 self.head

  1. def add_first(self, node):
  2. node.next = self.head
  3. self.head = node
  1. from LinkedList import LinkedList
  2. from Node import Node
  3. if __name__ == '__main__':
  4. llist = LinkedList()
  5. print(llist)
  6. llist.add_first(Node('b'))
  7. print(llist)
  8. llist.add_first(Node('a'))
  9. print(llist)

在尾部添加Node:必须遍历链表,与list不同,list可以直接获取长度, 链表只有从第一个Node,不断的去获取下一个Node 才能知道链表的尾部。

  1. def add_last(self, node):
  2. if self.head is None:
  3. self.head = node
  4. return
  5. for current_node in self:
  6. pass
  7. current_node.next = node
  1. from LinkedList import LinkedList
  2. from Node import Node
  3. if __name__ == '__main__':
  4. llist = LinkedList(['a','b','c','d'])
  5. print(llist)
  6. llist.add_last(Node('e'))
  7. print(llist)
  8. llist.add_last(Node('f'))
  9. print(llist)

在指定元素后添加Node:遍历链表找到目标Node, 把目标Node的下一个元素, 赋值给要添加Node的next属性, 然后修改目标Node的next属性, 指向新添加的Node, 当链表为空以及目标元素不存在时抛出异常。

  1. def add_after(self, target_node_data, new_node):
  2. if self.head is None:
  3. raise Exception("List is empty")
  4. for node in self:
  5. if node.data == target_node_data:
  6. new_node.next = node.next
  7. node.next = new_node
  8. return
  9. raise Exception("Node with data '%s' not found" % target_node_data)

在指定元素后添加Node:遍历链表找到目标Node, 把目标Node的下一个元素, 赋值给要添加Node的next属性, 然后修改目标Node的next属性, 指向新添加的Node, 当链表为空以及目标元素不存在时抛出异常。

  1. from LinkedList import LinkedList
  2. from Node import Node
  3. if __name__ == '__main__':
  4. llist = LinkedList()
  5. llist.add_after("a", Node("b"))
  6. llist = LinkedList(['a','b','c','d'])
  7. print(llist)
  8. llist.add_after("c", Node("cc"))
  9. print(llist)
  10. llist.add_after("f", Node("g"))

在指定元素前添加Node:遍历链表找到目标Node,还需要记录当前节点的前一个节点。

  1. def add_before(self, target_node_data, new_node):
  2. if self.head is None:
  3. raise Exception("List is empty")
  4. if self.head.data == target_node_data:
  5. return self.add_first(new_node)
  6. prev_node = self.head
  7. for node in self:
  8. if node.data == target_node_data:
  9. prev_node.next = new_node
  10. new_node.next = node
  11. return
  12. prev_node = node
  13. raise Exception("Node with data '%s' not found" % target_node_data)
  1. from LinkedList import LinkedList
  2. from Node import Node
  3. if __name__ == '__main__’:
  4. llist = LinkedList()
  5. llist.add_before("a", Node("b"))
  6. llist = LinkedList(["b", "c"])
  7. print(llist)
  8. llist.add_before('b',Node('a'))
  9. print(llist)
  10. llist.add_before("b", Node("aa"))
  11. llist.add_before("c", Node("bb"))
  12. print(llist)
  13. llist.add_before("n", Node("m"))

删除Node:遍历链表找到目标Node,将目标Node的前一个Node的next属性,指向目标Node的next节点。

  1. def remove_node(self, target_node_data):
  2. if self.head is None:
  3. raise Exception("List is empty")
  4. if self.head.data == target_node_data:
  5. self.head = self.head.next
  6. return
  7. previous_node = self.head
  8. for node in self:
  9. if node.data == target_node_data:
  10. previous_node.next = node.next
  11. return
  12. previous_node = node
  13. raise Exception("Node with data '%s' not found" % target_node_data)
  1. from LinkedList import LinkedList
  2. from Node import Node
  3. if __name__ == '__main__’:
  4. llist = LinkedList(["a", "b", "c", "d", "e"])
  5. print(llist)
  6. llist.remove_node("a")
  7. print(llist)
  8. llist.remove_node('e')
  9. print(llist)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/676412
推荐阅读
相关标签
  

闽ICP备14008679号