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.什么是链表? 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过 ...
随机推荐
- 【完美解决】2017打开MVC 4项目,cshtml页面提示‘当前上下文不存在名称model’
时间:2017/10/19 背景:领导让再之前的MVC 4老项目上新增功能,从GIT上拉取下来,使用VS2017打开之后,cshtml界面所有和Razor相关的代码均被提示‘当前上下文不存在名称XXX ...
- pm2用法详解+ecosystem.config
对于后台进程的管理,常用的工具是crontab,可用于两种场景:定时任务和常驻脚本.关于常驻脚本,今天介绍一款更好用的工具:pm2,基于nodejs开发的进程管理器,适用于后台常驻脚本管理,同时对no ...
- MySQL索引语法+使用场景
MySQL索引语法 建表时添加索引 建表同时建立单索引 CREATE TABLE t_user1(id INT , userName VARCHAR(20), PASSWORD VARCHAR(20) ...
- session多服务器共享的方案
session的存储了解以前是怎么做的,搞清楚了来龙去脉,才会明白进行共享背后的思想和出发点.我喜欢按照这样的方式来问(或者去搞清楚):为什么要session要进行共享,不共享会什么问题呢? php中 ...
- 在 JPA、Hibernate 和 Spring 中配置 Ehcache 缓存
jpa, hibernate 和 spring 时配置 ehcache 二级缓存的步骤. 缓存配置 首先在 persistence.xml 配置文件中添加下面内容: <property name ...
- 使用Java 8中的Stream
Stream是Java 8 提供的高效操作集合类(Collection)数据的API. 1. 从Iterator到Stream 有一个字符串的list,要统计其中长度大于7的字符串的数量,用迭代来实现 ...
- Servlet 笔记-异常处理
当一个 Servlet 抛出一个异常时,Web 容器在使用了 exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置. 必须在 web.xml 中使用 error-pa ...
- 微信小程序之给项目设置id后提示不在合法域名列别中
hotapp 有免费的https proxy ,可以免费代理请求任何http或者https服务,只要设置好合法域名为https://wxapi.hotapp.cn, 就可以请求网址如请求小程序联盟的例 ...
- Leetcode题解(十九)
54.Spiral Matrix 题目: 题目意思很简单,就是螺旋式访问矩阵元素.也没有比较经典的算法可以解决此题,只需要模拟一下这个过程即可. 代码如下: class Solution { publ ...
- A - 棋盘问题 POJ - 1321
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. ...