Python 单向链表、双向链表
用面向对象实现Linkedlist链表
单向链表实现append、iternodes
双向链表实现append、pop、insert、remove、iternodes
单向链表与双向链表

单向链表:
就好比小朋友在操场上,手拉着手。
分为数据域和指针域,指针域指向下一个数据,代码中分别用val 和next 表示。
整个链表用一个容器来存储,因为单向链表的数据虽然真正在内存中是散落的,但是某种关系可以把这些数据有序的组织起来,所以最合适的数据结构应该是列表。列表存储还支持追加和索引,容器在代码中用self.nodes=[] 表示。
如图:内存中的数据散落存储,5表示头head,9表示tail尾。

在链表为空时,需要定义头和尾,来表示前一个数据和下一个数据,头和尾在代码中用head 和tail 分别表示,前一个数据和下一个数据用prev 和next 分别表示。
0)链表数据为空时,顺序是:head --> tail,头和尾都可以用None表示;

1)链表中有一个数据时,顺序就变成了: head--> 数据1 -->tail;

2)链表有两个数据时,顺序变成了:head -->数据1 -->数据2 -->tail;

3)链表有三个数据时,顺序变成了:head -->数据1 -->数据2 -->数据3 -->tail

以此类推。。。
代码:
class SingleNode:
"""代表一个节点""" def __init__(self, val, next=None, prev=None):
self.val = val
self.next = next
self.prev = prev def __repr__(self):
return str(self.val) def __str__(self):
return str(self.val) class LinkedList:
"""容器类,某种方式存储一个个节点""" def __init__(self):
self.nodes = []
# 不需要插入的列表来说,检索方便,但是insert、remove不合适
self.head = None
self.tail = None def __len__(self):
return len(self.nodes) def __getitem__(self, item):
return self.nodes[item] def append(self, val):
node = SingleNode(val) # 实例化的一个新节点
prev = self.tail
if prev is None:
self.head = node
else:
prev.next = node
self.nodes.append(val)
self.tail = node def iternodes(self, reverse=False):
current = self.head
while current:
yield current
current = current.next ll = LinkedList()
ll.append(5)
ll.append(7) for node in ll.iternodes():
print(node) print(ll[0])
print(ll[1])
双向链表:
0) append 尾部追加
1) pop 尾部弹出
2) insert 头部插入、中间插入、尾部插入
3) remove 头部删除、中间删除、尾部删除
class SingleNode:
def __init__(self,val,next=None,prev=None):
self.val = val
self.next = next
self.prev = prev def __repr__(self):
return str(self.val) def __str__(self):
return str(self.val) class LinkedList:
def __init__(self):
# self.nodes = []
self.head = None
self.tail = None def append(self,val):
node = SingleNode(val)
# prev = self.tail
# if prev is None:
if self.head is None: #only one
self.head = node
else: # >1
self.tail.next = node
node.prev = self.tail
# self.nodes.append(node)
self.tail = node def iternodes(self,reverse=False):
current = self.tail if reverse else self.head
while current:
yield current
current = current.prev if reverse else current.next def pop(self):
if self.tail is None: #0个数据
raise Exception('Empty')
tail = self.tail
prev = tail.prev
# next = tail.next #尾的下一个恒定为None
if prev is None: # =0, =1
self.head = None
self.tail = None
else: # >1
self.tail = prev
prev.next = None
return tail.val def getitem(self,index): #index不考虑传入str类型,全当做int类型
if index < 0:
return None
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is not None:
return current def insert(self,index,val):
if index < 0: #不考虑负索引
raise Exception('Error')
current = None
for i, node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is None: #考虑元素为空、为一个
self.append(val)
return
#尾部、头部、中间追加
prev = current.prev
next = current.next node = SingleNode(val)
if prev is None: #头部插入
self.head = node
# node.next = current
# current.prev = node
else:
node.prev = prev
# node.next = current #和前面条件共同部分抽出来放后面
# current.prev = node
prev.next = node
node.next = current
current.prev = node def remove(self,index):
if self.tail is None:
raise Exception('Empty')
if index < 0:
raise ValueError('Wrong Index {}'.format(index)) current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is None: #Not found
raise ValueError('Wrong Index {}. Out of boundary'.format(index)) prev = current.prev
next = current.next if prev is None and next is None: #only one node
self.head = None
self.tail = None
elif prev is None: #删头部
self.head = next
next.prev = None
elif next is None: #删尾部
self.tail = prev
prev.next = None
else: #中间
prev.next = next
next.prev = prev del current # def __getitem__(self, item):
# return self.nodes[item] ll = LinkedList()
ll.append('abc')
ll.append(1)
ll.append(2)
ll.append(3)
ll.append(4)
ll.append(5)
ll.append('def') ll.insert(6,6) #边界
ll.insert(7,7) #尾部
ll.insert(8,8) #尾部
ll.insert(0,123) #头部
ll.insert(100,100) #超界 # ll.remove(100) # ll.pop()
# ll.pop() for node in ll.iternodes(False): #False
print(node)
print('~'*30)
# print(ll[0])
# print(ll[1])
ll.remove(5)
ll.remove(6)
ll.remove(0)
ll.remove(1)
for node in ll.iternodes(False): #False
print(node)
Python 单向链表、双向链表的更多相关文章
- Python单向链表的实现
链表由一系列不必在内存中相连的结构构成,这些对象按线性顺序排序.每个结构含有表元素和指向后继元素的指针.最后一个单元的指针指向NULL.为了方便链表的删除与插入操作,可以为链表添加一个表头. 删除操作 ...
- python 单向链表实现
单链表的操作 is_empty() 链表是否为空 length() 链表长度 travel() 遍历整个链表 add(item) 链表头部添加元素 append(item) 链表尾部添加元素 inse ...
- python 单向链表
import sys import random class employee: def __init__(self): self.num= self.salary= self.name='' sel ...
- Python链表的实现与使用(单向链表与双向链表)
参考[易百教程]用Python实现链表及其功能 """ python链表的基本操作:节点.链表.增删改查 """ import sys cl ...
- 用Python写单向链表和双向链表
链表是一种数据结构,链表在循环遍历的时候效率不高,但是在插入和删除时优势比较大. 链表由一个个节点组成. 单向链表的节点分为两个部分:存储的对象和对下一个节点的引用.注意是指向下一个节点. 而双向链表 ...
- python数据结构链表之单向链表
单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域ele ...
- 玩转C线性表和单向链表之Linux双向链表优化
前言: 这次介绍基本数据结构的线性表和链表,并用C语言进行编写:建议最开始学数据结构时,用C语言:像栈和队列都可以用这两种数据结构来实现. 一.线性表基本介绍 1 概念: 线性表也就是关系户中最简单的 ...
- 用python实现单向链表
单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域ele ...
- Java-链表(单向链表、双向链表)
Java-链表 1.什么是链表? 2.链表的特点是什么? 3.链表的实现原理? 4.如何自己写出一个链表? 1.什么是链表? 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过 ...
随机推荐
- MyBatis开发中解决返回字段不全的问题
场景重现: mybatis 在查询的时候,可以返回Map,但是一旦这个字段为空(null)的时候,map里就没有了.我用的是mysql数据库,除了在查询语句上做ifnull判断给它默认值外,有没的别的 ...
- VS中Release模式下生成去掉生成pdb文件
1.右键项目,选择属性 2.选择正确的配置,点击高级 3.调试信息选择 none,点击确定.
- 解题笔记-洛谷-P1010 幂次方
0 题面 题目描述 任何一个正整数都可以用2的幂次方表示.例如 137=2^7+2^3+2^0 同时约定方次用括号来表示,即a^b 可表示为a(b). 由此可知,137可表示为: 2(7)+2(3)+ ...
- springcloud之服务注册与发现(Eureka)
springcloud服务注册与发现 使用Eureka实现服务治理 作用:实现服务治理(服务注册与发现) 简介: Spring Cloud Eureka是Spring Cloud Netflix项目下 ...
- WAMPServer配置修改及问题汇总
备忘录 软件版本wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-64b -------------------------------------- ...
- wordpress 显示数学公式 (MathJax-LaTeX)
blog 不放一堆数学公式怎么能显得高大上,所以 MathJax-LaTeX 也是必装的插件之一了. 一.安装 MathJax-LaTex 插件 直接在 wordpress 插件中,搜索并安装 Mat ...
- ALV添加文字输入框
一.业务场景 在合同打印中,需要临时添加其他约定事项,在打印程序的ALV中添加其他事项字段,点击之后弹出文字输入窗口,点击确定,文字内容存表,并在ALV中展示,点击打印后,文字内容加载到smartfo ...
- ASP.NET没有魔法——ASP.NET 身份验证与Identity
前面的文章中为My Blog加入了文章的管理功能(ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块),但是管理功能应该只能由“作者”来访问,那么要如何控制用户的访问权限?也 ...
- MongoDB用户权限管理
创建用户账号: (roles参数指定了用户的角色以及这个账号授权的数据库,在同一个数据库中不能同时创建两个用户名相同的账号) Mongodb内置的用户角色: 数据库用户角色:read.readWrit ...
- jerasure 2.0译文
原文地址: 本文译者水平有限,如发现问题请批评指正 Jerasure 2.0:为方便存储相关应用开发的一个基于C开发的纠删码库 版本2.0 James S.Plank Kevin M.Greenan ...