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.什么是链表? 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过 ...
随机推荐
- 【转载】CSS3 Transitions, Transforms和Animation使用简介与应用展示
文章转载自 张鑫旭-鑫空间-鑫生活 http://www.zhangxinxu.com/wordpress/ 原文链接:http://www.zhangxinxu.com/wordpress/?p=1 ...
- Android onSaveInstanceState和onRestoreInstanceState()
首先来介绍onSaveInstanceState() 和 onRestoreInstanceState() .关于这两个方法,一些朋友可能在Android开发过程中很少用到,但在有时候掌握其用法会帮我 ...
- 安装xp遇到的问题与如何连接共享的打印机
2013-12-5 星期四 今天下午去给曹老师鼓捣电脑去了,安装了一个xp系统,加上一些常用的办公软件,在连接上一个共享的打印机. 下面是今天我遇到的问题: 问题:安装xp系统之后,没有本地连接,只有 ...
- Mongodb 认证鉴权那点事
[TOC] 一.Mongodb 的权限管理 认识权限管理,说明主要概念及关系 与大多数数据库一样,Mongodb同样提供了一套权限管理机制. 为了体验Mongodb 的权限管理,我们找一台已经安装好的 ...
- [译]ASP.NET Core 2.0 中间件
问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...
- Web Fragment在项目中的使用
Web Fragment 是什么 - 它是在 servlet 3.0开始支持的,可以把一个dy web项目拆分为多个项目,解耦合,使其在项目中开发效率提高,下面我演示简单的项目创建过程 用eclips ...
- 获取Django项目的全部url
在为一个项目添加权限时,遇到一个问题,就是为项目所有的url设置权限,但是一个一个手动输入太麻烦了,所以考虑用代码获取到一个项目所有的url 首先,考虑到项目最外层的urlpartterns,因为所有 ...
- Windows环境下多线程编程原理与应用读书笔记(6)————临界段及其应用
<一>临界段 临界段对象通过提供所有线程必须共享的对象来控制线程.只有拥有临界段对象的线程才能够访问保护的资源.在另一个线程可以访问该资源之前,前一线程必须释放临界段对象,一遍新的线程可以 ...
- A. 拼音魔法
A. 拼音魔法 Time limit per test: 1.0 seconds Time limit all tests: 1.0 seconds Memory limit: 256 megabyt ...
- #define is unsafe
#define is unsafe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...