• 数据结构---python---表


    一、list的基本实现技术

          在数据结构中,如果用python实现线性表,无疑要提到list,list是一种元素个数可变的线性表(而tuple是不变的表,不支持改变其内部状态的任何操作,其他与list性质类似),采用分离式技术实现的动态顺序表,表中元素保存在一块连续存储区内。实现约束有如下两点:

    1、基于下标(位置)的高效元素访问和更新,时间复杂度是O(1)

    2、允许任意添加元素,不可以出现由于表满而无法加入新元素的情况;而且在添加新元素之后,表对象标识不变。

    在python的官方实现中,list的实现策略如下:

    1、在建立空表(或很小的表)时,系统分配一块能容纳8个元素的存储区;
    2、在执行insert或append等操作来扩充表时,如果元素区满就换一块4倍大的存储区,把所有元素copy过去;
    3、如果当前的表已经“很大”(这里阈值为50000),系统将改变策略,换存储区时容量加倍,这是为了避免出现过多的空闲存储位置。

    注:python没有提供检查一个list对象的当前存储块容量的操作,也没有设置容量的操作,一切与容量有关的处理都由Python解释器自动完成,这和c++、java等有很大的区别。优点是降低了编程的负担,避免人为操作可能引进的错误。但全部交给解释器来完成也限制了表的使用方式。

    小练习:list的内置方法reverse,自己实现的方法:

     1 def my_reverse(lst):
     2     elems = lst
     3     i,j = 0, len(elems)-1
     4     while i <j:
     5         elems[i], elems[j] = elems[j], elems[i]  #这里交换元素写在一行,不需要设置中间的temp作为交换媒介
     6         i,j = i+1, j-1
     7     return elems
     8 a = [1,2,3,4,5,"a"]
     9 print a
    10 print '
    after my reverse',my_reverse(a)

    二、单链表类的实现

    单链表的基础知识就不往上贴了,下面贴个python实现的实现类

    1、利用循环创建一个简单的单链表

     1 # -*- coding:utf-8 -*-
     2 '''
     3 简单的循环调用一个长度为10的单链表
     4 '''
     5 class LNode:  #实现单链表的节点类
     6     def __init__(self,elem, next_=None):
     7         self.elem = elem
     8         self.next = next_  #以next_命名,避免与标准函数next重名,这是python的命名习惯
     9 
    10 llist1 = LNode(1)
    11 p = llist1
    12 
    13 for i in range(2,11):
    14     p.next = LNode(i)
    15     p = p.next
    16 
    17 p = llist1  #把链表的指针重新指向第一个节点
    18 while p:
    19     print p.elem
    20     p = p.next

    2、单链表类的实现

     1 # -*- coding:utf-8 -*-
     2 __author__ = 'webber'
     3 '''单链表类的实现'''
     4 
     5 class LNode:  #实现单链表的节点类
     6     def __init__(self,elem, next_=None):
     7         self.elem = elem
     8         self.next = next_  #以next_命名,避免与标准函数next重名,这是python的命名习惯
     9 
    10 class LinkedListUnderflow(ValueError):  #继承标准异常的子类ValueError
    11     pass
    12 
    13 class LList:
    14     def __init__(self):
    15         self._head = None
    16 
    17     def is_empty(self):
    18         return self._head is None
    19 
    20     def prepend(self,elem):
    21         self._head = LNode(elem,self._head)
    22 
    23     def pop(self):
    24         if self._head is None: #无结点,引发异常
    25             raise LinkedListUnderflow("in pop")
    26         ele = self._head.elem
    27         self._head = self._head.next
    28         return ele
    29 
    30     def pop_last(self):    #这里有两个特殊情况,表为空,或者表中只有一个元素,pop掉最后一个元素的时间复杂度为O(n)
    31         if self._head is None: #空表,无结点,引发异常
    32             raise LinkedListUnderflow("in pop_last")
    33         p = self._head
    34         if p.next is None:  #表中只有一个元素
    35             ele = p.elem
    36             self._head = None
    37             return ele
    38         while p.next.next is not None:  #直到p.next是最后的结点
    39             p = p.next
    40         ele = p.next.elem
    41         p.next = None
    42         return ele
    43 
    44     def append(self, elem):
    45         if self._head is None:
    46             self._head = LNode(elem)
    47             return
    48         p = self._head
    49         while p.next:
    50             p = p.next
    51         p.next = LNode(elem)
    52 
    53     def printall(self):
    54         p = self._head
    55         while p:
    56             print p.elem,
    57             if p.next:
    58                 print ",",
    59             p = p.next
    60         print ""
    61 
    62 mlist1 = LList()
    63 print mlist1.is_empty()
    64 for i in range(10):
    65     mlist1.prepend(i)
    66 for i in range(11,20):
    67     mlist1.append(i)
    68 mlist1.printall()
    69 print mlist1.is_empty()
    70 for i in range(5):
    71     mlist1.pop()
    72 print "pop 5 个数据之后:"
    73 mlist1.printall()

    3、表的遍历

    python语言为内部汇集类型提供的遍历机制是迭代器,标准使用方式是放在for语句头部,在循环体中逐个处理汇集对象的元素,用yield实现。可在上面的单链表类中添加如下方法:

    1  def elements(self):
    2         p = self._head
    3         while p is not None:
    4             yield p.elem    #返回结点元素
    5             p = p.next
    6     
    7  for i in mlist1.elements():
    8     print i,

    筛选生成器:下面是一个筛选生成器的方法,可以将单链表中所有符合条件的结点元素返回,这里需要注意两点:一是关于yield和return的用法区别,yield使这个方法变成一个迭代器,每一次循环迭代器使用next方法返回一个值,而return如果执行的话,整个函数就结束了。二是这里在调用该方法时需要一个“判断谓词参数”,在python中可以使用lambda表达式定制这个操作参数,方法和调用如下:

    1  def filter(self,pred):      #筛选生成器
    2         p = self._head
    3         while p:
    4             if pred(p.elem):
    5                 yield p.elem
    6             p = p.next
    7             
    8 for i in mlist1.filter(lambda i:i>10):    #谓词参数,返回单链表中元素大于10的元素
    9     print i,
  • 相关阅读:
    改进神经网络及深度学习的学习方法
    caffe+win7+vs2013 仅CPU环境安装
    读书笔记--C陷阱与缺陷(七)
    读书笔记--C陷阱与缺陷(六)
    读书笔记--C陷阱与缺陷(五)
    读书笔记--C陷阱与缺陷(四)
    读书笔记--C陷阱与缺陷(三)
    搭建centos7的开发环境3-Spark安装配置
    Spark学习笔记
    Python2和Python3比较分析
  • 原文地址:https://www.cnblogs.com/webber1992/p/6057738.html
Copyright © 2020-2023  润新知