python链表_手把手实现 python 的链表数据结构
python 标准库并没有实现链表,所以我们得自己实现链表。
什么是链表
链表是计算机科学中最常用的数据结构之一。它也是最简单的结构之一,也是更高层结构(如堆栈、循环缓冲区和队列)的基础。
一般来说,列表是通过引用连接的单个数据元素的集合。C程序员知道这是指针。例如,数据元素可以由地址数据、地理数据、几何数据、路由信息或事务细节组成。通常,链接列表的每个元素都具有特定于列表的相同数据类型
单个列表元素称为节点。节点不同于顺序存储在内存中的数组。相反,它可能会在不同的内存段中找到它们,您可以通过跟踪从一个节点到下一个节点的指针找到这些内存段。通常使用nil元素标记列表的结尾,该元素由python等效的None表示。
链表类型
单链表
有两种列表-单链接列表和双链接列表。单个链接列表中的节点只指向列表中的下一个元素,而双链接列表中的节点也指向上一个节点。数据结构占用更多的空间,因为您需要一个额外的变量来存储链表的引用。
@单链列表
双链表
一个链表可以从头到尾遍历,而反向遍历则比较难。相反,双链接列表允许以相同的成本在两个方向上遍历节点,无论从哪个节点开始。此外,添加和删除节点以及拆分单个链接列表的步骤不超过两个。在双链接列表中,必须更改四个指针。(详情可见添加删除方法)
@双链表
这篇博文,我们将一步步建立自己的链表。首先,我们为节点创建一个对应的数据结构。其次,您将学习如何实现和使用一个单链接列表,最后是一个双链接列表。
Step 1: Node as a Data Structure
我们建立一个Node 的节点类。该类有两个属性变量存储数据的data和指向下一个节点的引用next。
__init_(): 初始化节点的方法
self.data: 储存在节点中的数据
self.next: 下个节点的引用
has_value(): 是否包含这个值的节点
# 1。__init_(): initialize the node with the data
# 2。self.data: the value stored in the node
# 3。self.next: the reference pointer to the next node
# 4。 has_value(): compare a value with the node value
class Node:
def __init__(self, data):
"constructor to initiate this object"
# store data
self.data = data
# store reference (next item)
self.next = None
return
def has_value(self, value):
"method to compare the value with the node data"
if self.data == value:
return True
else:
return False
Step 2: Creating a Class for a Single-Linked List
这一步我们建立一个叫 SingleLinkedList 的类。该类包含一下方法
__init__(): 初始化方法
list_length():返回节点数
output_list(): 打印方法
add_list_item(): 添加一个节点到list 中
unordered_search(): 在列表中查找具有指定值的节点
remove_list_item_by_id(): 通过节点id 移除节点
初始化方法
定 head 和tail属性
class SingleLinkedList:
def __init__(self):
"constructor to initiate this object"
self.head = None
self.tail = None
return
添加
def add_list_item(self, item):
"add an item at the end of the list"
#如果不是 Node,构建为Node
if not isinstance(item, Node):
item = Node(item)
#如果头节点是空,则当前节点就是 item
if self.head is None:
self.head = item
else:
#如果已经有头节点,则加到尾部
self.tail.next = item
#尾部就是当前绩点item了
self.tail = item
return
定义返回节点长度方法
def list_length(self):
"returns the number of list items"
count = 0
current_node = self.head
while current_node is not None:
# increase counter by one
count = count + 1
# jump to the linked node
current_node = current_node.next
return count
定义输出方法
def output_list(self):
"outputs the list (the value of the node, actually)"
current_node = self.head
while current_node is not None:
print(current_node.data)
# jump to the linked node
current_node = current_node.next
return
查询
查询列表,返回指定值的node 位置list
def unordered_search(self, value):
"search the linked list for the node that has this value"
# define current_node
current_node = self.head
# define position
node_id = 1
# define list of results
results = []
while current_node is not None:
if current_node.has_value(value):
results.append(node_id)
# jump to the linked node
current_node = current_node.next
node_id = node_id + 1
return results
删除
def remove_list_item_by_id(self, item_id):
"remove the list item with the item id"
current_id = 1
current_node = self.head
previous_node = None
while current_node is not None:
#当前这个node 就是需要移除的node
if current_id == item_id:
# if this is the first node (head)
#如果这个node 前面还有node ,那需要把前面node 的next,指向当前node 的下一个node(原来前一个node 的next 是当前node)。
# 就已经从这个链路里移除了,因为没有node 指向它了。
if previous_node is not None:
previous_node.next = current_node.next
else:
#需要移除的是第一个node,只要把当前的head 指向下一个node 即可
self.head = current_node.next
# we don't have to look any further
return
# needed for the next iteration
# 如果还不是当前node,上一个node 变成当前node
# 当前node 变成当前node 的下一个。当然id 要加1
previous_node = current_node
current_node = current_node.next
current_id = current_id + 1
return
测试以上方法
我们使用一下代码,测试下以上方法。
# create three single nodes
node1 = ListNode(15)
node2 = ListNode(8.2)
node3 = ListNode("Berlin")
node4 = ListNode(15)
track = DoubleLinkedList()
print("track length: %i" % track.list_length())
for current_node in [node1, node2, node3, node4]:
track.add_list_item(current_node)
print("track length: %i" % track.list_length())
track.output_list()
results = track.unordered_search(15)
print(results)
track.remove_list_item_by_id(4)
track.output_list()
Step 3: Creating a Double-Linked List
本来我们可以通过继承的方式,复用 Node 方法。但为了更清晰。我们再建立一个Node2 作为基本节点。
class Node2:
def __init__(self, data):
"constructor class to initiate this object"
# store data
self.data = data
# store reference (next item)
self.next = None
# store reference (previous item)
self.previous = None
return
def has_value(self, value):
"method to compare the value with the node data"
if self.data == value:
return True
else:
return False
建立 DoubleLinkedList
from Add_Two_Numbers.Node2 import Node2
class DoubleLinkedList:
def __init__(self):
"constructor to initiate this object"
self.head = None
self.tail = None
return
def list_length(self):
"returns the number of list items"
count = 0
current_node = self.head
while current_node is not None:
# increase counter by one
count = count + 1
# jump to the linked node
current_node = current_node.next
return count
def output_list(self):
"outputs the list (the value of the node, actually)"
current_node = self.head
while current_node is not None:
print(current_node.data)
# jump to the linked node
current_node = current_node.next
return
def unordered_search (self, value):
"search the linked list for the node that has this value"
# define current_node
current_node = self.head
# define position
node_id = 1
# define list of results
results = []
while current_node is not None:
if current_node.has_value(value):
results.append(node_id)
# jump to the linked node
current_node = current_node.next
node_id = node_id + 1
return results
#略有不同
def add_list_item(self, item):
"add an item at the end of the list"
if isinstance(item, Node2):
#如果还没有Node,则首尾都是item,而且该node 的前一个没有,后一个也没有
if self.head is None:
self.head = item
item.previous = None
item.next = None
self.tail = item
else:
#如果有Node 元素了,则当前尾部的node的下一个node 就是item,item的前一个元素就是当前的tail node。现在把item 放到尾部。
self.tail.next = item
item.previous = self.tail
self.tail = item
return
#根据node id 移除node
def remove_list_item_by_id(self, item_id):
"remove the list item with the item id"
current_id = 1
current_node = self.head
#当前node 不为空
while current_node is not None:
previous_node = current_node.previous
next_node = current_node.next
#当前node 就是需要移除的node
if current_id == item_id:
# if this is the first node (head)
#当前node 不是第一个head node
if previous_node is not None:
#前一个node的 next 指向 下个node
previous_node.next = next_node
# 如果当前node 不是tail node
if next_node is not None:
# next_node 前一个node 指向 当前node 的前一个node(原来next_node 的前一个node 是 当前node)
next_node.previous = previous_node
else:
#如果需要移除的是head node,则把head 指向 next_node
self.head = next_node
# 如果 head node 不是最后一个node ,则还要把下一个node 的 previous 指向为None(原来为当前node)
if next_node is not None:
next_node.previous = None
# we don't have to look any further
return
# needed for the next iteration
current_node = next_node
current_id = current_id + 1
return
总结
链表作为数据结构易于实现,并且提供了很大的使用灵活性。这是用几行代码完成的。作为改进,您可以添加一个节点计数器(count),它只保存列表中节点的数量。这样可以把查询列表长度复杂度降低到 O(1),您不必遍历整个列表。
python链表_手把手实现 python 的链表数据结构相关推荐
- python卸载_手把手教Python环境安装
Anaconda集成环境 Python3.7 如果是linux环境包括MacOs,系统环境中会默认安装python2.7. 尽量量不不要卸载linux环境中的默认python环境,直接安装Python ...
- python没有指针如何实现链表_[转]为什么python标准库没有实现链表
实际上刚开始学习一些高级语言的时候我也有同样的疑问,而且即使有链表对应物的语言,链表常常也很少被实际使用. 如果是在国外听数据结构的课,老师一般会警告你这只是一个理论概念,实际应用应该实际考察,在通常 ...
- python编的俄罗斯方块游戏_手把手制作Python小游戏:俄罗斯方块(一)
手把手制作Python小游戏:俄罗斯方块1 大家好,新手第一次写文章,请多多指教 A.准备工作: 这里我们运用的是Pygame库,因为Python没有内置,所以需要下载 如果没有pygame,可以到官 ...
- python图形小游戏代码_手把手制作Python小游戏:俄罗斯方块(一)
手把手制作Python小游戏:俄罗斯方块1 大家好,新手第一次写文章,请多多指教 A.准备工作: 这里我们运用的是Pygame库,因为Python没有内置,所以需要下载 如果没有pygame,可以到官 ...
- python 多核并行计算_手把手 | 嫌Python太慢?并行运算Process Pools三行代码给你4倍提速!...
大数据文摘作品,转载要求见文末 作者 | Adam Geitgey 编译 | 元元.Lisa.Saint.Aileen 原文链接 | https://medium.com/@ageitgey/quic ...
- python 切片_全面解读Python高级特性切片
大家好,欢迎来到Crossin的编程教室! 众所周知,我们可以通过索引值(或称下标)来查找序列类型(如字符串.列表.元组-)中的单个元素,那么,如果要获取一个索引区间的元素该怎么办呢? 切片(slic ...
- python 堆排序_堆排序用python
Python天天美味(30) - python数据结构与算法之快速排序 快速排序的原理是将取出第一个数,将整个数组分为两波,一拨都大于这个数,另一波都小于这个数,然后递归用同样的方法处理第一波数字和第 ...
- 学习python课程_想学习Python吗? 这是我们的免费4小时互动课程
学习python课程 Python is a popular, versatile and easy-to-learn language. It's the go-to language for AI ...
- 2018年python薪资_最好的Python:2017和2018年至今我最喜欢的文章集
2018年python薪资 我打算发布此收藏集 (My intention with publishing this collection) Last year I only used Medium ...
最新文章
- SAP零售:补货 Vs 多步骤补货
- 工控攻防演示——从外网到内网控制系统设备的入侵
- 计算机网络与影视多媒体技术 南京理工大学,计算机网络多媒体数学库和课件结构设计-计算机仿真论文-计算机论文(8页)-原创力文档...
- 台北到淡水版Firefox无法播放视频
- Servlet页面跳转实现方法的区别
- solr6.6+jetty+centos+mysql
- 黄聪:Delphi 日期格式问题 - is not a valid date
- endnote大客户版_Endnote软件的使用,有图有干货!
- RocketMQ安装使用
- Flask 框架 是 Python 中最流行的 Web 框架之一
- 苹果好还是华为好_苹果手机好还是华为手机好?专业手机测评师给出答复!
- 1、pandas使用sort_values排序
- UVC系列2-探索Android UVC协议
- word课程表设置符号与编号_小学生课程表word模板 小学生使用WORD.doc
- C语言实现简单 词法分析程序(编译原理)
- linux下运行workman,笔记:Linux(AWS Redhat)开机启动workman进程(/etc/rc.local必须是755权限)...
- html 正方形字符,HTML常用标签以及特殊符号
- 对象可以创建数组吗_企业微信活码如何创建?活码可以统计渠道来源吗?
- Process finished with exit code 134
- 永善县黄华镇大永高速通车了
热门文章
- linux 解压缩一个文件夹下所有的压缩文件
- 初学关键段容易忽略的问题
- 去除eclipse打开后不断update的问题
- 杭电1596find the safest road
- 给定单链表,检测是否有环等系列考题
- html 如何 创建目录,html - javascript:如何自动生成一篇文章的目录
- python编程(关于cocos2d)
- python编程(改进的线程同步方式)
- jq自动获取html的值,jquery如何获取class值?
- linux 多块硬盘 snmp,[技术干货] Zabbix使用snmp监控Linux硬盘大小不准问题