数据结构之线性表(python版)
数据结构之线性表(python版)
单链表
1.1 定义表节点
# 定义表节点
class LNode():
def __init__(self,elem,next = None): self.elem = elem
self.next = next_1.2 单向链表
# LList 类的定义 单链表 (单向) class LList():
def __init__(self): # 这里并没有继承 LNode类 在加入数据时候引用了 LNode类 self.head = None def is_empty(self):
return self._head is None def prepend(self,elem): # 在表头插入数据 # 时间复杂度是O(1) self._head = LNode(elem,self._head) # 这里体现了基于节点类LNode 定义 def pop(sefl):
''' 返回表头的数据,并删除该数据
时间复杂度是 O(1) '''
if self._head is None: # 无节点
raise LinkedListUnderflow("in pop .")
e = self._head.elem
self._head = self._head.next
return e def append(self,elem):
# 尾端操作数据 首先要找到尾端节点
# 时间复杂度O(n) ,n 是节点的个数
if self._head is None :
self._head = LNode(elem)
return
p = self._head
while p.next :
p = p.next
p.next = LNode(elem) def pop_last(self):
# 弹出尾端数据,并删除
# 时间复杂度是 O(n),n 是节点个数
if self._head is None :
raise LinkedUnderflow(" in pop_last . ")
p = self._head
if p.next is None : # 表中只有一个数据
e = p.elem
self._head = None
return e
while p.next.next : # 这里的逻辑容易搞混,注意判断条件
p = p.next
e = p.next.elem
p.next = None
return e def find(self,pred):
# 查找满足条件的元素
# pred 是可以作用于表元素的函数
p = self._head
while p:
if pred(p.elem):
return p.elem
p = p.next def printall(self): # 打印表中所有元素
p = self._head
while p :
print(p.elem,end=" ")
if p.next :
print(', ',end="")
p = p.next
print('') def for_each(self,proc):
# for_each 是类似于 map zip 函数
# proc 是可以作用于表元素的函数 p = self._head
while p :
proc(p.elem)
p = p.next def elements(self):
'''
定义生成器 函数
'''
p = self._head
while p :
yield p.elem
p = p.next def filter(self,pred):
'''
定义筛选生成器 函数
'''
p = self._head
while p :
if pred(p.elem) :
yield p.elem
p = p.next def rev(self):
p = None
while self._head :
q = self._head
self._head = q.next
q.next = p
p = q
self._head = p1.3 单向链表变形
1.31 增加尾节点引用域_rear LList1 单链表变形类# 增加尾节点引用域_rear LList1 单链表变形类 class LList1(LList): # 比单纯的单链表类 增加了尾节点引用域_rear def __init__(self):
LList.__init__(self)
self._rear = None def prepend(self,elem): # 前端插入
self._head = LNode(elem)
if self._head :
self._rear = self._head
else :
self._head = LNode(elem,self._head) def append(self,elem): # 尾端插入
if self._head is None :
self._head = LNode(elem)
self._rear = self._head
else :
self._rear.next = LNode(elem)
self._rear = self._rear.next def pop_last(self): # 尾端弹出
if self._head is None :
raise LinkedUnderflow(" in pop_last() . ")
p = self._head
if p.next is None : # 如果只有一个元素
e = self._head
self._head = None
return e
while p.next.next :
p = p.next
e = p.next.elem
p.next = None
self._rear = p
return e1.32 循环单链表类的定义 LCList
# 循环单链表类的定义 LCList class LCList():
'''
循环单链表中的 _rear 在逻辑上始终引用着表的结尾
'''
def __init__(self):
self._rear = None def is_empty(self):
return self._rear is None def prepend(self,elem): # 前端插入
p = LNode(elem)
if self._rear is None : # 建立一个节点的环
p.next = p
self._rear = p
else :
p.next = self._rear.next
self._rear.next = p def append(self,elem): # 后端插入
prepend(elem)
slef._rear = self._rear.next def pop(self): # 前端弹出
if self._rear is None :
raise LinkedUnderflow(" in pop of CLList . ")
p = self._rear.next
if self._rear is p :
self._rear = None
else :
self._rear.next = p.next
return p.elem def printall(self): # 输出表元素
if self.is_empty():
return
p = self._rear
while True :
print(p.elem)
if p is self._rear :
break
p = p.next双链表
双链表与单链表的区别在于,双链表比单链表多了个反向引用域 prev2.1 双链表类节点的定义 DLNode
# 双链表节点类 DLNode class DLLNode(LNode):
''' 双链表节点类 '''
def __init__(self,elem,prev=None,next_=None):
LNode.__init__(self,elem,next_)
self.prev = prev # 反向引用域2.2 双链表的定义
基于单链表类 LList1 派生出 DLList ,个别方法不需要重新定义# 双链表节点类 DLNode class DLLNode(LNode):
'''
双链表节点类
'''
def __init__(self,elem,prev=None,next_=None) :
LNode.__init__(self,elem,next_)
self.prev = prev # 定义双链表 DDList class DLList(LList1): # 有两个引用域,一个是next 另一个是反向 prev def __init__(self):
LList.__init__(self) def perpend(sefl,elem) : # 前端加入
p = DLNode(elem,None,self._head) # 这里已经做了 p.next_=self._head
if self._head is None :
self._rear = p
else :
p.next.prev = p
# p.next = self._head 这一步在加入elem元素时就做了
self._head = p def append(self,elem): # 后端加入
p = DLNode(elem,self._rear,None) # 这里已经做了 p.prev = self._rear
if self._head is None : # 空表
self._head = p
else : # 非空表 设置 next 引用
p.prev.next = p
self._rear = p def pop(self): # 前端弹出
if self._head is None :
raise LinkedUnderflow(" in pop of DLList . ")
e = self._head.elem
self._head = self._head.next
if self._head :
self._head.prev = None
return e def pop_last(self) : # 尾端弹出
if self._head is None :
raise LinkedUnderflow(" in pop_last of DLList . ")
e = self._rear.elem
self._rear = self._rear.prev
if self._rear is None :
self._head = None # 设置_head=None 保证is_empty正常工作
else :
self._rear.next = None
return e2.3 循环双链表
数据结构之线性表(python版)的更多相关文章
- 数据结构之 栈 (Python 版)
数据结构之 栈 (Python 版) -- 利用线性表实现栈 栈的特性: 后进先出 基于顺序表实现栈 class SStack(): ''' 基于顺序表 实现的 栈类 ''' def __init__ ...
- 数据结构之队列(Python 版)
数据结构之队列(Python 版) 队列的特点:先进先出(FIFO) 使用链表技术实现 使用单链表技术,在表首尾两端分别加入指针,就很容易实现队列类. 使用顺序表list实现 # 队列类的实现 cla ...
- 用C#学习数据结构之线性表
什么是线性表 线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系.这种一对一的关系指的是数据元素之间的位置关 ...
- C语言数据结构-顺序线性表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作
1.数据结构-顺序线性表的实现-C语言 #define MAXSIZE 100 //结构体定义 typedef struct { int *elem; //基地址 int length; //结构体当 ...
- 算法与数据结构(一) 线性表的顺序存储与链式存储(Swift版)
温故而知新,在接下来的几篇博客中,将会系统的对数据结构的相关内容进行回顾并总结.数据结构乃编程的基础呢,还是要不时拿出来翻一翻回顾一下.当然数据结构相关博客中我们以Swift语言来实现.因为Swift ...
- 【Java】 大话数据结构(1) 线性表之顺序存储结构
本文根据<大话数据结构>一书,实现了Java版的顺序存储结构. 顺序存储结构指的是用一段地址连续的存储单元一次存储线性表的数据元素,一般用一维数组来实现. 书中的线性表抽象数据类型定义如 ...
- 【Java】 大话数据结构(2) 线性表之单链表
本文根据<大话数据结构>一书,实现了Java版的单链表. 每个结点中只包含一个指针域的链表,称为单链表. 单链表的结构如图所示: 单链表与顺序存储结构的对比: 实现程序: package ...
- 【Java】 大话数据结构(5) 线性表之双向链表
本文根据<大话数据结构>一书,实现了Java版的双向链表. 在每个数据结点中都有两个指针,分别指向直接后继和直接前驱,这样的链表称为双向链表. 双向链表的结构如图所示: 查找元素可以根据元 ...
- [C++]数据结构:线性表之顺序表
1 顺序表 ADT + Status InitList(SeqList &L) 初始化顺序表 + void printList(SeqList L) 遍历顺序表 + int ListLengt ...
随机推荐
- loj2542 「PKUWC2018」随机游走 【树形dp + 状压dp + 数学】
题目链接 loj2542 题解 设\(f[i][S]\)表示从\(i\)节点出发,走完\(S\)集合中的点的期望步数 记\(de[i]\)为\(i\)的度数,\(E\)为边集,我们很容易写出状态转移方 ...
- [CQOI2016] 手机号码 (数位dp)
link $solution:$ $10^{10} \leq L \leq R < 10^{11}$这个数据范围很容易想到数位$dp$. 依照题意模拟即可. #include<iostre ...
- 树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)
前提是数的范围较小 1 数据范围:O(n) 2 查第k大的数i:log(n)(树状数组查询小于等于i的数目)*log(n)(二分找到i) 3 添加:log(n) (树状数组) 4 删除:log(n) ...
- joda-time 2.5 包简化java时间操作
原文:https://www.ibm.com/developerworks/cn/java/j-jodatime.html Joda-Time 简介 既然无法摆脱时间,为何不设法简化时间处理? J P ...
- 题解【bzoj1503 [NOI2004]郁闷的出纳员】
Description 给出一个下限 \(m\) ,要求维护以下操作 插入一个数(如果小于下限就不加) 给每个数加上一个数 给每个数减去一个数,并且删除掉 \(< m\) 的所有数 求目前第 \ ...
- GCC、GNU C、C99、ANSI C
ANSI C ANSI C是由美国国家标准协会(ANSI)及国际标准化组织(ISO)推出的关于C语言的标准.ANSI C 标准同时规定了 C 标准库. ANSI C发展历史 C 的第一个标准是由ANS ...
- Kubernetes--kubectl
一.Kubectl命令行说明 类型 命令 描述 基础命令 create 通过文件名或标准输入创建资源 expose 将一个资源公开为一个新的kubernetes服务 run 创建并运行一个特定的镜 ...
- etcd启用https服务
目录 cfssl相关工具下载 生成etcd所需要的ssl证书 生成ca证书 生成etcd服务端证书 生成etcd客户端证书 修改etcd集群配置文件 重启etcd集群 验证集群健康情况 关于etcd的 ...
- 利用Sentinel实现Redis主从切换
利用Sentinel(哨兵)实现Redis集群的故障自主切换 首先部署redis主从集群,主要安装过程: cd redis make make install 主要看配置文件: master: bin ...
- UIScrollView增加回弹效果
项目中经常要增加上下滑动回弹的效果: self.scrollView.alwaysBounceVertical = YES;