数据结构之线性表(python版)

  1. 单链表

    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 = p
    
    

    1.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 e

    1.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
  2. 双链表

    双链表与单链表的区别在于,双链表比单链表多了个反向引用域 prev

    2.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 e
    
    

    2.3   循环双链表

数据结构之线性表(python版)的更多相关文章

  1. 数据结构之 栈 (Python 版)

    数据结构之 栈 (Python 版) -- 利用线性表实现栈 栈的特性: 后进先出 基于顺序表实现栈 class SStack(): ''' 基于顺序表 实现的 栈类 ''' def __init__ ...

  2. 数据结构之队列(Python 版)

    数据结构之队列(Python 版) 队列的特点:先进先出(FIFO) 使用链表技术实现 使用单链表技术,在表首尾两端分别加入指针,就很容易实现队列类. 使用顺序表list实现 # 队列类的实现 cla ...

  3. 用C#学习数据结构之线性表

    什么是线性表 线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系.这种一对一的关系指的是数据元素之间的位置关 ...

  4. C语言数据结构-顺序线性表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作

    1.数据结构-顺序线性表的实现-C语言 #define MAXSIZE 100 //结构体定义 typedef struct { int *elem; //基地址 int length; //结构体当 ...

  5. 算法与数据结构(一) 线性表的顺序存储与链式存储(Swift版)

    温故而知新,在接下来的几篇博客中,将会系统的对数据结构的相关内容进行回顾并总结.数据结构乃编程的基础呢,还是要不时拿出来翻一翻回顾一下.当然数据结构相关博客中我们以Swift语言来实现.因为Swift ...

  6. 【Java】 大话数据结构(1) 线性表之顺序存储结构

     本文根据<大话数据结构>一书,实现了Java版的顺序存储结构. 顺序存储结构指的是用一段地址连续的存储单元一次存储线性表的数据元素,一般用一维数组来实现. 书中的线性表抽象数据类型定义如 ...

  7. 【Java】 大话数据结构(2) 线性表之单链表

    本文根据<大话数据结构>一书,实现了Java版的单链表. 每个结点中只包含一个指针域的链表,称为单链表. 单链表的结构如图所示: 单链表与顺序存储结构的对比: 实现程序: package ...

  8. 【Java】 大话数据结构(5) 线性表之双向链表

    本文根据<大话数据结构>一书,实现了Java版的双向链表. 在每个数据结点中都有两个指针,分别指向直接后继和直接前驱,这样的链表称为双向链表. 双向链表的结构如图所示: 查找元素可以根据元 ...

  9. [C++]数据结构:线性表之顺序表

    1 顺序表 ADT + Status InitList(SeqList &L) 初始化顺序表 + void printList(SeqList L) 遍历顺序表 + int ListLengt ...

随机推荐

  1. 【ARC083E】Bichrome Tree

    Description ​ 给一棵\(n\)个节点的树,和一个长度同样为\(n\)的非负整数序列\(x_i\). ​ 请尝试对每个节点染黑或白两种颜色,并确定一个非负整数权值. ​ 问是否存在一种方案 ...

  2. Android字体设置

    // 自定义字体custom = new TextView(this);//xx.ttf located at assets/fonts/typeface = Typeface.createFromA ...

  3. 【bzoj4084】【sdoi2015】双旋转字符串

    题解 首先题中说了$n>=m$; 分成的循环串左右两边为本质相同的单循环串循环串,分别长为$l = \frac{n + m}{2} $; 所以$S$串的前$l$位为双循环串的一半$S1$,后一半 ...

  4. 【AC自动机】AC自动机

    Definition & Solution AC自动机是一种多模式串的字符串匹配数据结构,核心在于利用 fail 指针在失配时将节点跳转到当前节点代表字符串的最长后缀子串. 首先对 模式串 建 ...

  5. MySQL 第四篇:数据操作

    一 介绍 MySQL数据操作: DML ======================================================== 在MySQL管理软件中,可以通过SQL语句中的 ...

  6. Linux发不出分片包的问题分析

    今日有个网络攻击模拟需求,要打分片的ip包,程序写好了,在开发机上验证也没问题,然后部署到沙盒环境之后不行,就是发不出来数据包,而不分片的数据包能够正常发送,定位过程如下 1.对比了两台机器/proc ...

  7. github怎么绑定自己的域名

    本文前提是你已经搭建好了博客. CAST: 1 没有域名的话先去申请一个域名 如果想简单省心,不计较时间和金钱的话,那就阿里云或腾讯云买全套大宝剑(服务器+域名+解析). 因为本人不想备案(时间长), ...

  8. GO_05_2:Golang 中 panic、recover、defer 的用法

     函数 defer 1. 它的执行方式类似其他语言中的折构函数,在函数体执行结束后按照调用顺序的 相反顺序 逐个执行 2. 即使函数发生 严重错误 也会被执行,类似于 java 中 try{...} ...

  9. Chapter One:数据结构和算法-解压序列赋值给多个变量

    一.问题: 现在有一个包含 N 个元素的元组或者是序列,怎样将它里面的值解压后同时赋值给 N 个变量? 二.解决方案: 代码示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 ...

  10. Node.js 被分叉出一个项目 — Ayo.js,肿么了

    (注:ayo.js叉从Node.js.目前,大量的文档仍然指向Node.js库.) ayo.js是一个JavaScript运行时建立在Chrome的V8 JavaScript引擎.ayo.js使用事件 ...