Python_Example_ Data Structures and Algorithm Analysis 学习/示例

 Author: 楚格

2018-11-19   19:05:11

IDE: Pycharm2018.02   Python 3.7   

KeyWord :  Data Structures and Algorithm Analysis 

Explain:  

 

 

---------------------------------------------

---------

   1 # coding=utf-8
   2 #---------------------------------
   3 '''
   4 # Author  : chu ge 
   5 # Function:  Data Structures and Algorithm Analysis
   6 #
   7 '''
   8 #---------------------------------
   9 '''
  10 # --------------------------------
  11 # 导入模块 
  12 # 1.系统库
  13 # 2.第三方库
  14 # 3.相关定义库
  15 # --------------------------------
  16 '''
  17 # 1.系统库
  18 import sys
  19 import os
  20 import time
  21 import timeit # 性能分析
  22 from timeit import Timer
  23 
  24 #2.第三方库
  25 
  26 
  27 #
  28 '''
  29 ============================================================================
  30 #》》》》》》》》》》》》》》
  31 
  32 Data Structures and Algorithm Analysis
  33 
  34 ----------------------------------------------
  35 1. 概念
  36 -----------------------
  37 # 
  38 e.g:
  39 if __name__ == "__main__":
  40 result:
  41 -----------------------
  42 1.1 第一次尝试
  43 
  44 -----------------------
  45 1.2算法的提出
  46 
  47 算法是独立存在的一种解决问题的方法和思想。
  48 对于算法而言,实现的语言并不重要,重要的是思想。
  49 
  50 算法的五大特性
  51 有输入: 算法具有0个或多个输入
  52 有输出: 算法至少有1个或多个输出
  53 有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
  54 确定性: 算法中的每一步都有确定的含义,不会出现二义性
  55 可行性: 算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成
  56 
  57 -----------------------
  58 1.3 第二次尝试
  59 
  60 -----------------------
  61 1.4 算法效率衡量
  62 
  63 执行时间反应算法效率
  64 对于同一问题,我们给出了两种解决算法,在两种算法的实现中,
  65 我们对程序执行的时间进行了测算,发现两段程序执行的时间相差悬殊
  66 (214.583347秒相比于0.182897秒),
  67 由此得出结论:实现算法程序的执行时间可以反应出算法的效率,即算法的优劣。
  68 
  69 时间复杂度与“大O记法”
  70 我们假定计算机执行算法每一个基本操作的时间是固定的一个时间单位,
  71 那么有多少个基本操作就代表会花费多少时间单位。
  72 算然对于不同的机器环境而言,确切的单位时间是不同的,
  73 但是对于算法进行多少个基本操作(即花费多少时间单位),在规模数量级上却是相同的,
  74 由此可以忽略机器环境的影响而客观的反应算法的时间效率。
  75 
  76 
  77 对于算法的时间效率,我们可以用“大O记法”来表示。
  78 “大O记法”:
  79 对于单调的整数函数f,如果存在一个整数函数g和实常数c>0,使得对于
  80 充分大的n总有f(n)<=c*g(n),就说函数g是f的一个渐近函数(忽略常数),
  81 记为f(n)=O(g(n))。也就是说,在趋向无穷的极限意义下,
  82 函数f的增长速度受到函数g的约束,亦即函数f与函数g的特征相似。
  83 
  84 时间复杂度:
  85 假设存在函数g,使得算法A处理规模为n的问题示例所用时间为
  86 T(n)=O(g(n)),则称O(g(n))为算法A的渐近时间复杂度,简称时间复杂度,记为T(n)
  87 
  88 
  89 如何理解“大O记法”
  90 对于算法进行特别具体的细致分析虽然很好,但在实践中的实际价值有限。
  91 对于算法的时间性质和空间性质,最重要的是其数量级和趋势,
  92 这些是分析算法效率的主要部分。而计量算法基本操作数量的规模函数中,
  93 那些常量因子可以忽略不计。例如,可以认为3n2和100n2属于同一个量级,
  94 如果两个算法处理同样规模实例的代价分别为这两个函数,
  95 就认为它们的效率“差不多”,都为n2级。
  96 
  97 
  98 最坏时间复杂度
  99 
 100 分析算法时,存在几种可能的考虑:
 101 算法完成工作最少需要多少基本操作,即最优时间复杂度。
 102 算法完成工作最多需要多少基本操作,即最坏时间复杂度。
 103 算法完成工作平均需要多少基本操作,即平均时间复杂度。
 104 对于最优时间复杂度,其价值不大,因为它没有提供什么有用信息,
 105 其反映的只是最乐观最理想的情况,没有参考价值。
 106 对于最坏时间复杂度,提供了一种保证,表明算法在此种程度的基本操作中一定能完成工作。
 107 对于平均时间复杂度,是对算法的一个全面评价,因此它完整全面的反映了这个算法的性质。
 108 但另一方面,这种衡量并没有保证,不是每个计算都能在这个基本操作内完成。
 109 而且,对于平均情况的计算,也会因为应用算法的实例分布可能并不均匀而难以计算。
 110 因此,我们主要关注算法的最坏情况,亦即最坏时间复杂度。
 111 
 112 
 113 
 114 时间复杂度的几条基本计算规则:
 115 
 116 基本操作,即只有常数项,认为其时间复杂度为O(1)
 117 顺序结构,时间复杂度按加法进行计算
 118 循环结构,时间复杂度按乘法进行计算
 119 分支结构,时间复杂度取最大值
 120 判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
 121 在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
 122 
 123 -----------------------
 124 1.7 python 内置类型性能分析
 125 
 126 timeit模块
 127 timeit模块可以用来测试一小段Python代码的执行速度。
 128 
 129 class timeit.Timer(
 130                     stmt='pass', 
 131                     setup='pass', 
 132                     timer=<timer function>
 133                    )
 134 Timer:是测量小段代码执行速度的类。
 135 stmt:参数是要测试的代码语句(statment);
 136 setup:参数是运行代码时需要的设置;
 137 timer:参数是一个定时器函数,与平台有关。
 138 
 139 #通常使用
 140 timeit.Timer.timeit(number=1000000)
 141 
 142 Timer:类中测试语句执行速度的对象方法。可替换!!!
 143 number:参数是测试代码时的测试次数,默认为1000000次。
 144      方法返回执行代码的平均耗时,一个float类型的秒数。
 145 
 146 e.g:
 147 
 148 def Function_Test_A():
 149     l = []
 150     for i in range(1000):
 151         l = l + [i]
 152 
 153 def Function_Test_B():
 154     l = []
 155     for i in range(1000):
 156         l.append(i)
 157 
 158 def Function_Test_C():
 159     l = [i for i in range(1000)]
 160 
 161 def Function_Test_D():
 162     l = list(range(1000))
 163     
 164 if __name__ == "__main__":
 165     # 固定格式
 166     #创建对象:函数名 测试代码语句  运行代码设置
 167     time_A = Timer("Function_Test_A()", "from __main__ import Function_Test_A")
 168     # 执行速度设置 固定格式
 169     print("time_A:", time_A.timeit(number=100), "seconds")
 170 
 171     time_B = Timer("Function_Test_B()", "from __main__ import Function_Test_B")
 172     print("time_B ", time_B.timeit(number=100), "seconds")
 173     time_C = Timer("Function_Test_C()", "from __main__ import Function_Test_C")
 174     print("time_C ", time_C.timeit(number=100), "seconds")
 175     time_D = Timer("Function_Test_D()", "from __main__ import Function_Test_D")
 176     print("time_D ", time_D.timeit(number=100), "seconds")
 177     #
 178 
 179 result:
 180 
 181 -----------------------
 182 1.8 数据结构
 183 
 184 
 185 数据是一个抽象的概念,将其进行分类后得到程序设计语言中的基本类型。
 186 如:int,float,char等。数据元素之间不是独立的,存在特定的关系,
 187 这些关系便是结构。数据结构指数据对象中数据元素之间的关系。
 188 
 189 Python给我们提供了很多现成的数据结构类型,这些系统自己定义好的,
 190 不需要我们自己去定义的数据结构叫做Python的内置数据结构,
 191 比如列表、元组、字典。而有些数据组织方式,Python系统里面没有直接定义,
 192 需要我们自己去定义实现这些数据的组织方式,这些数据组织方式称之为Python的扩展数据结构,比如栈,队列等。
 193 
 194 算法与数据结构的区别
 195 数据结构只是静态的描述了数据元素之间的关系。
 196 高效的程序需要在数据结构的基础上设计和选择算法。
 197 
 198 程序 = 数据结构 + 算法
 199 
 200 总结:算法是为了解决实际问题而设计的,数据结构是算法需要处理的问题载体.
 201 
 202 抽象数据类型(Abstract Data Type)
 203 抽象数据类型(ADT)的含义是指一个数学模型以及定义在此数学模型上的一组操作。
 204 即把数据类型和数据类型上的运算捆在一起,进行封装。
 205 引入抽象数据类型的目的是,把数据类型的表示和数据类型上运算的实现,
 206 与这些数据类型和运算在程序中的引用隔开,使它们相互独立。
 207 
 208 最常用的数据运算有五种:
 209 1.插入
 210 2.删除
 211 3.修改
 212 4.查找
 213 5.排序
 214 
 215 ----------------------------------------------
 216 2. 顺序表
 217 
 218 在程序中,经常需要将一组(通常是同为某个类型的)数据元素作为整体管理和使用,
 219 需要创建这种元素组,用变量记录它们,传进传出函数等。
 220 一组数据中包含的元素个数可能发生变化(可以增加或删除元素)。
 221 
 222 对于这种需求,最简单的解决方案便是将这样一组元素看成一个序列,
 223 用元素在序列里的位置和顺序,表示实际应用中的某种有意义的信息,
 224 或者表示数据之间的某种关系。
 225 
 226 这样的一组序列元素的组织形式,我们可以将其抽象为线性表。
 227 一个线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系。
 228 线性表是最基本的数据结构之一,在实际程序中应用非常广泛,
 229 它还经常被用作更复杂的数据结构的实现基础。
 230 
 231 
 232 根据线性表的实际存储方式,分为两种实现模型:
 233 
 234 顺序表,将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。
 235 
 236 链表,将元素存放在通过链接构造起来的一系列存储块中。
 237 -----------------------
 238 2.1 顺序表的基本形式
 239 
 240 图a表示的是顺序表的基本形式,数据元素本身连续存储,每个元素所占的存储单元大小固定相同,
 241 元素的下标是其逻辑地址,而元素存储的物理地址(实际内存地址)
 242 可以通过存储区的起始地址Loc (e0)加上逻辑地址(第i个元素)
 243 与存储单元大小(c)的乘积计算而得,即:Loc(ei) = Loc(e0) + c*i
 244 故,访问指定元素时无需从头遍历,通过计算便可获得对应地址,其时间复杂度为O(1)。
 245 如果元素的大小不统一,则须采用图b的元素外置的形式,将实际数据元素另行存储,
 246 而顺序表中各单元位置保存对应元素的地址信息(即链接)。
 247 由于每个链接所需的存储量相同,通过上述公式,可以计算出元素链接的存储位置,
 248 而后顺着链接找到实际存储的数据元素。注意,图b中的c不再是数据元素的大小,
 249 而是存储一个链接地址所需的存储量,这个量通常很小。
 250 图b这样的顺序表也被称为对实际数据的索引,这是最简单的索引结构。
 251 
 252 -----------------------
 253 2.2 顺序表的结构与实现
 254 
 255 顺序表的结构
 256 一个顺序表的完整信息包括两部分,一部分是表中的元素集合,
 257 另一部分是为实现正确操作而需记录的信息,即有关表的整体情况的信息,
 258 这部分信息主要包括元素存储区的容量和当前表中已有的元素个数两项。
 259 
 260 顺序表的两种基本实现方式
 261 顺序表的实现方式
 262 图a为一体式结构,存储表信息的单元与元素存储区以连续的方式安排在
 263 一块存储区里,两部分数据的整体形成一个完整的顺序表对象。一体式结
 264 构整体性强,易于管理。但是由于数据元素存储区域是表对象的一部分,
 265 顺序表创建后,元素存储区就固定了。
 266 
 267 图b为分离式结构,表对象里只保存与整个表有关的信息(即容量和元素个
 268 数),实际数据元素存放在另一个独立的元素存储区里,通过链接与基本表
 269 对象关联。
 270 
 271 元素存储区替换
 272 一体式结构由于顺序表信息区与数据区连续存储在一起,所以若想更换数据区,
 273 则只能整体搬迁,即整个顺序表对象(指存储顺序表的结构信息的区域)改变了。
 274 
 275 分离式结构若想更换数据区,只需将表信息区中的数据区链接地址更新即可,
 276 而该顺序表对象不变。
 277 
 278 元素存储区扩充
 279     采用分离式结构的顺序表,若将数据区更换为存储空间更大的区域,
 280 则可以在不改变表对象的前提下对其数据存储区进行了扩充,所有使用这
 281 个表的地方都不必修改。只要程序的运行环境(计算机系统)还有空闲存
 282 储,这种表结构就不会因为满了而导致操作无法进行。人们把采用这种技
 283 术实现的顺序表称为动态顺序表,因为其容量可以在使用中动态变化。
 284 
 285 扩充的两种策略
 286     每次扩充增加固定数目的存储位置,如每次扩充增加10个元素位置,
 287 这种策略可称为线性增长。
 288     特点:节省空间,但是扩充操作频繁,操作次数多。每次扩充容量加倍,
 289 如每次扩充增加一倍存储空间。
 290     特点:减少了扩充操作的执行次数,但可能会浪费空间资源。以空间换
 291 时间,推荐的方式。
 292 -----------------------
 293 2.3 顺序表的操作
 294 
 295 顺序表增加元素
 296 a. 尾端加入元素,时间复杂度为O(1)
 297 b. 非保序的加入元素(不常见),时间复杂度为O(1)
 298 c. 保序的元素加入,时间复杂度为O(n)
 299 
 300 删除元素
 301 顺序表删除元素
 302 a. 删除表尾元素,时间复杂度为O(1)
 303 b. 非保序的元素删除(不常见),时间复杂度为O(1)
 304 c. 保序的元素删除,时间复杂度为O(n)
 305 -----------------------
 306 2.4 Python中的顺序表
 307     Python中的list和tuple两种类型采用了顺序表的实现技术,具有
 308 前面讨论的顺序表的所有性质。tuple是不可变类型,即不变的顺序表,因
 309 此不支持改变其内部状态的任何操作,而其他方面,则与list的性质类似。
 310 list的基本实现技术。Python标准类型list就是一种元素个数可变的线
 311 性表,可以加入和删除元素,并在各种操作中维持已有元素的顺序(即保序
 312 ),而且还具有以下行为特征:
 313     基于下标(位置)的高效元素访问和更新,时间复杂度应该是O(1);
 314 为满足该特征,应该采用顺序表技术,表中元素保存在一块连续的存储区中。
 315 允许任意加入元素,而且在不断加入元素的过程中,表对象的标识(函数
 316 id得到的值)不变。为满足该特征,就必须能更换元素存储区,并且为保
 317 证更换存储区时list对象的标识id不变,只能采用分离式实现技术。
 318 
 319     在Python的官方实现中,list就是一种采用分离式技术实现的动态
 320 顺序表。这就是为什么用list.append(x) (或 list.insert(len
 321 (list), x),即尾部插入)比在指定位置插入元素效率高的原因。
 322 
 323     在Python的官方实现中,list实现采用了如下的策略:在建立空表
 324 (或者很小的表)时,系统分配一块能容纳8个元素的存储区;在执行插入
 325 操作(insert或append)时,如果元素存储区满就换一块4倍大的存储区。
 326 但如果此时的表已经很大(目前的阀值为50000),则改变策略,采用加一
 327 倍的方法。引入这种改变策略的方式,是为了避免出现过多空闲的存储位置。
 328 
 329 ----------------------------------------------
 330 3. 链表
 331 
 332 为什么需要链表
 333     顺序表的构建需要预先知道数据大小来申请连续的存储空间,
 334 而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活。
 335 链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。
 336 
 337 链表的定义
 338 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是
 339 不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放
 340 下一个节点的位置信息(即地址)。
 341 
 342 -----------------------
 343 3.1 单向链表
 344 
 345     单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包
 346 含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下
 347 一个节点,而最后一个节点的链接域则指向一个空值。
 348 *表元素域elem用来存放具体的数据。
 349 *链接域next用来存放下一个节点的位置(python中的标识)
 350 *变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。
 351 
 352 节点实现
 353 class Class_Single_Node(object):
 354     # 单链表的结点
 355     def __init__(self,item):
 356         # _item存放数据元素
 357         self.item = item
 358         # _next是下一个节点的标识
 359         self.next = None
 360         
 361 单链表的操作
 362 length()     链表长度
 363 travel()     遍历整个链表
 364 is_empty()   链表是否为空
 365 add(item)    链表头部添加元素
 366 append(item) 链表尾部添加元素
 367 remove(item) 删除节点
 368 search(item) 查找节点是否存在
 369 insert(pos, item) 指定位置添加元素
 370 
 371 单链表的操作实现
 372 e.g:
 373 # 单链表
 374 #节点实现
 375 class Class_Single_Node(object):
 376     # 单链表的结点
 377     def __init__(self,item):
 378         # _item存放数据元素
 379         self.item = item
 380         # _next是下一个节点的标识
 381         self.next = None
 382 
 383 #单链表的操作实现
 384 class SingleLinkList(object):
 385     # 单链表头文件
 386     def __init__(self):
 387         self._head = None
 388 
 389     # 判断链表是否为空
 390     def is_empty(self):
 391         return self._head == None
 392 
 393     # 链表长度
 394     def length(self):
 395         # cur初始时指向头节点
 396         current = self._head
 397         count = 0
 398         # 尾节点指向None,当未到达尾部时
 399         while current != None:
 400             count  += 1
 401             current = current.next # 将cur后移一个节点
 402         return count
 403 
 404     # 遍历链表
 405     def travel(self):
 406         current = self._head
 407         while current != None:
 408             print ("Travel  Item : [%s]"%(current.item))
 409             current = current.next
 410         print ("Current Item : (%s)" % (current))
 411 
 412     # 头部添加元素
 413     def add(self, item):
 414         # 先创建一个保存item值的节点 这是创建的前提条件
 415         Node = Class_Single_Node(item)
 416         # 将新节点的链接域next指向头节点,即_head指向的位置
 417         Node.next = self._head
 418         # 将链表的头_head指向新节点
 419         self._head = Node
 420 
 421     # 尾部添加元素
 422     def append(self, item):
 423         Node = Class_Single_Node(item)
 424         # 先判断链表是否为空,若是空链表,则将_head指向新节点
 425         if self.is_empty():
 426             self._head = Node
 427         # 若不为空,则找到尾部,将尾节点的next指向新节点
 428         else:
 429             current = self._head
 430             while current.next != None:
 431                 current = current.next
 432             current.next = Node
 433 
 434     # 指定位置添加元素
 435     def insert(self, pos, item):
 436         # 若指定位置pos为第一个元素之前,则执行头部插入
 437         if pos <= 0:
 438             self.add(item)
 439         # 若指定位置超过链表尾部,则执行尾部插入
 440         elif pos > (self.length()-1):
 441             self.append(item)
 442         # 找到指定位置
 443         else:
 444             Node = Class_Single_Node(item)  # 创建新的列表
 445             count = 0
 446             # pre用来指向指定位置pos的前一个位置pos-1,初始从头节点开始移动到指定位置
 447             previous = self._head
 448             while count < (pos-1):
 449                 count += 1
 450                 previous = previous.next
 451             # 先将新节点node的next指向插入位置的节点
 452             Node.next = previous.next
 453             # 将插入位置的前一个节点的next指向新节点
 454             previous.next = Node
 455 
 456     # 删除节点
 457     def remove(self,item):
 458         current = self._head
 459         previous = None
 460         while current != None:
 461             # 找到了指定元素
 462             if current.item == item:
 463                 # 如果第一个就是删除的节点
 464                 if not previous:
 465                     # 将头指针指向头节点的后一个节点
 466                     self._head = current.next
 467                 else:
 468                     # 将删除位置前一个节点的next指向删除位置的后一个节点
 469                     previous.next = current.next
 470                 break
 471             else:
 472                 # 继续按链表后移节点
 473                 previous = current
 474                 current = current.next
 475 
 476     #查找节点是否存在
 477     def search(self,item):
 478         # 表查找节点是否存在,并返回True或者False
 479         current = self._head
 480         while current != None:
 481             if current.item == item:
 482                 return True
 483             current = current.next
 484         return False
 485 
 486 
 487 if __name__ == "__main__":
 488     single_list_name_A = SingleLinkList()
 489     single_list_name_A.add(11)       # 头部添加元素
 490     single_list_name_A.add(12)       # 头部添加元素
 491     single_list_name_A.add(13)       # 头部添加元素
 492     single_list_name_A.append(24)    # 尾部添加元素
 493     single_list_name_A.insert(3, 35) # 指定位置添加元素
 494     single_list_name_A.append(26)    # 尾部添加元素
 495     single_list_name_A.travel()      # 遍历链表
 496     print ("Length:[%s]"%(single_list_name_A.length()))
 497     print(single_list_name_A.search(35)) # 查找节点是否存在
 498     print(single_list_name_A.search(15)) # 查找节点是否存在
 499     single_list_name_A.remove(11)        # 删除节点
 500     single_list_name_A.travel()          # 遍历链表
 501     print("Length:[%s]" % (single_list_name_A.length()))
 502 result:
 503     Travel  Item : [13]
 504     Travel  Item : [12]
 505     Travel  Item : [11]
 506     Travel  Item : [35]
 507     Travel  Item : [24]
 508     Travel  Item : [26]
 509     Current Item : (None)
 510     Length:[6]
 511     True
 512     False
 513     Travel  Item : [13]
 514     Travel  Item : [12]
 515     Travel  Item : [35]
 516     Travel  Item : [24]
 517     Travel  Item : [26]
 518     Current Item : (None)
 519     Length:[5] 
 520     
 521 链表与顺序表的对比
 522     链表失去了顺序表随机读取的优点,同时链表由于增加了结点的指针域,
 523 空间开销比较大,但对存储空间的使用要相对灵活。
 524 链表与顺序表的各种操作复杂度如下所示:
 525 
 526 操作    链表    顺序表
 527 访问元素            O(n)    O(1)
 528 在头部插入/删除    O(1)    O(n)
 529 在尾部插入/删除    O(n)    O(1)
 530 在中间插入/删除    O(n)    O(n)
 531     注意虽然表面看起来复杂度都是 O(n),但是链表和顺序表在插入和
 532 删除时进行的是完全不同的操作。链表的主要耗时操作是遍历查找,删除和
 533 插入操作本身的复杂度是O(1)。顺序表查找很快,主要耗时的操作是拷贝
 534 覆盖。因为除了目标元素在尾部的特殊情况,顺序表进行插入和删除时需要
 535 对操作点之后的所有元素进行前后移位操作,只能通过拷贝和覆盖的方法进行。
 536 
 537 -----------------------
 538 3.2 单向循环链表
 539     单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再
 540 为None,而是指向链表的头节点。
 541 
 542 单向循环链表操作
 543 is_empty() 判断链表是否为空
 544 length() 返回链表的长度
 545 travel() 遍历
 546 add(item) 在头部添加一个节点
 547 append(item) 在尾部添加一个节点
 548 insert(pos, item) 在指定位置pos添加节点
 549 remove(item) 删除一个节点
 550 search(item) 查找节点是否存在
 551 
 552 e.g:
 553 # 单向循环链表
 554 # 单项节点创建
 555 # class Class_Single_Node(object):
 556 #     # 单链表的结点
 557 #     def __init__(self,item):
 558 #         # _item存放数据元素
 559 #         self.item = item
 560 #         # _next是下一个节点的标识
 561 #         self.next = None
 562 
 563 class Class_SinCyc_Linkedlist(object):
 564     def __init__(self):
 565         self._head = None
 566 
 567     # 判断链表是否为空
 568     def is_empty(self):
 569         return self._head == None
 570 
 571     # 返回链表的长度
 572     def length(self):
 573         # 如果链表为空,返回长度0
 574         if self.is_empty():
 575             return 0
 576         count = 1
 577         current = self._head
 578         while current.next != self._head:
 579             count += 1
 580             current = current.next
 581         return count
 582 
 583     # 遍历链表
 584     def travel(self):
 585         # 判断是否为空
 586         if self.is_empty():
 587             return
 588         current = self._head
 589         print("Travel  Item : [%s]" % (current.item))
 590         while current.next != self._head:
 591             current = current.next
 592             print("Travel  Item : [%s]" % (current.item))
 593         print("Travel Finish ")
 594 
 595     # 头部添加节点
 596     def add(self, item):
 597         Node = Class_Single_Node(item)
 598         # 判断是否为空
 599         if self.is_empty():
 600             self._head = Node
 601             Node.next = self._head
 602         else:
 603             #添加的节点指向_head
 604             Node.next = self._head
 605             # 移到链表尾部,将尾部节点的next指向node
 606             current = self._head
 607             while current.next != self._head:
 608                 current = current.next
 609             current.next = Node
 610             #_head指向添加node的
 611             self._head = Node
 612     # 尾部添加节点
 613     def append(self, item):
 614         Node = Class_Single_Node(item)
 615         if self.is_empty():
 616             self._head = Node
 617             Node.next = self._head
 618         else:
 619             # 移到链表尾部
 620             current = self._head
 621             while current.next != self._head:
 622                 current = current.next
 623             # 将尾节点指向node
 624             current.next = Node
 625             # 将node指向头节点_head
 626             Node.next = self._head
 627     # 指定位置添加节点
 628     def insert(self, pos, item):
 629         if pos <= 0:
 630             self.add(item)
 631         elif pos > (self.length()-1):
 632             self.append(item)
 633         else:
 634             Node = Class_Single_Node(item)
 635             current = self._head
 636             count = 0
 637             # 移动到指定位置的前一个位置
 638             while count < (pos-1):
 639                 count += 1
 640                 current = current.next
 641             Node.next = current.next
 642             current.next = Node
 643 
 644     def remove(self, item):
 645         """删除一个节点"""
 646         # 若链表为空,则直接返回
 647         if self.is_empty():
 648             return
 649         # 将cur指向头节点
 650         current = self._head
 651         pre = None
 652         # 若头节点的元素就是要查找的元素item
 653         if current.item == item:
 654             # 如果链表不止一个节点
 655             if current.next != self._head:
 656                 # 先找到尾节点,将尾节点的next指向第二个节点
 657                 while current.next != self._head:
 658                     current = current.next
 659                 # cur指向了尾节点
 660                 current.next = self._head.next
 661                 self._head = self._head.next
 662             else:
 663                 # 链表只有一个节点
 664                 self._head = None
 665         else:
 666             pre = self._head
 667             # 第一个节点不是要删除的
 668             while current.next != self._head:
 669                 # 找到了要删除的元素
 670                 if current.item == item:
 671                     # 删除
 672                     pre.next = current.next
 673                     return
 674                 else:
 675                     pre = current
 676                     current = current.next
 677             # current 指向尾节点
 678             if current.item == item:
 679                 # 尾部删除
 680                 pre.next = current.next
 681     # 查找节点是否存在
 682     def search(self, item):
 683         if self.is_empty():
 684             return False
 685         current = self._head
 686         if current.item == item:
 687             return True
 688         while current.next != self._head:
 689             current = current.next
 690             if current.item == item:
 691                 return True
 692         return False
 693 
 694 if __name__ == "__main__":
 695     # 单链表循环
 696     single_list_name_B = Class_SinCyc_Linkedlist()
 697     print("Length:[%s]" % (single_list_name_B.length()))
 698     single_list_name_B.add(11)          # 头部添加元素
 699     single_list_name_B.add(12)          # 头部添加元素
 700     single_list_name_B.add(13)          # 头部添加元素
 701     single_list_name_B.append(21)       # 尾部添加元素
 702     single_list_name_B.insert(1, 31)    # 指定位置添加元素
 703     single_list_name_B.insert(3, 32)    # 指定位置添加元素
 704     single_list_name_B.insert(5, 33)    # 指定位置添加元素
 705     single_list_name_B.append(22)       # 尾部添加元素
 706     single_list_name_B.travel()         # 遍历链表
 707     print("Length:[%s]" % (single_list_name_B.length()))
 708     print(single_list_name_B.search(11))# 查找节点是否存在
 709     print(single_list_name_B.search(22))# 查找节点是否存在
 710     print(single_list_name_B.search(55))# 查找节点是否存在
 711     single_list_name_B.remove(11)
 712     single_list_name_B.travel()  # 遍历链表
 713     print("Length:[%s]" % (single_list_name_B.length()))
 714     #
 715 result:
 716     Length:[0]
 717     Travel  Item : [13]
 718     Travel  Item : [31]
 719     Travel  Item : [12]
 720     Travel  Item : [32]
 721     Travel  Item : [11]
 722     Travel  Item : [33]
 723     Travel  Item : [21]
 724     Travel  Item : [22]
 725     Travel Finish 
 726     Length:[8]
 727     True
 728     True
 729     False
 730     Travel  Item : [13]
 731     Travel  Item : [31]
 732     Travel  Item : [12]
 733     Travel  Item : [32]
 734     Travel  Item : [33]
 735     Travel  Item : [21]
 736     Travel  Item : [22]
 737     Travel Finish 
 738     Length:[7]
 739 
 740 -----------------------
 741 3.3 双向链表
 742 
 743     一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链
 744 接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一
 745 个指向下一个节点,当此节点为最后一个节点时,指向空值。
 746 
 747 双向链表操作
 748     is_empty() 链表是否为空
 749     length() 链表长度
 750     travel() 遍历链表
 751     add(item) 链表头部添加
 752     append(item) 链表尾部添加
 753     insert(pos, item) 指定位置添加
 754     remove(item) 删除节点
 755     search(item) 查找节点是否存在
 756 
 757 e.g:
 758 # 双向链表节点
 759 class Class_Double_Node(object):
 760     def __init__(self, item):
 761         # _item存放数据元素
 762         self.item = item
 763         # _next是下一个节点的标识
 764         self.next = None
 765         # _prev是上一个节点的标识
 766         self.prev = None
 767 
 768 # 双向链表操作
 769 class Class_Double_LinkList(object):
 770     def __init__(self):
 771         self._head = None
 772 
 773     # 判断链表是否为空
 774     def is_empty(self):
 775         return self._head == None
 776     
 777     # 链表的长度
 778     def length(self):
 779         current = self._head
 780         count = 0
 781         while current != None:
 782             count += 1
 783             current = current.next
 784         return count
 785     
 786     # 遍历链表
 787     def travel(self):
 788         current = self._head
 789         while current != None:
 790             print("Travel  Item : [%s]" % (current.item))
 791             current = current.next
 792         print("Travel Finish ")
 793     
 794     # 头部插入元素
 795     def add(self, item):
 796         Node = Class_Double_Node(item)
 797         # 如果是空链表,将_head指向node
 798         if self.is_empty():
 799             self._head = Node
 800         else:
 801             # 将node的next指向_head的头节点
 802             Node.next = self._head
 803             # 将_head的头节点的prev指向node
 804             self._head.prev = Node
 805             # 将_head 指向node
 806             self._head = Node
 807 
 808     # 尾部插入元素
 809     def append(self, item):
 810         Node = Class_Double_Node(item)
 811         # 如果是空链表,将_head指向node
 812         if self.is_empty():
 813             self._head = Node
 814         else:
 815             # 移动到链表尾部
 816             current = self._head
 817             while current.next != None:
 818                 current = current.next
 819             # 将尾节点cur的next指向node
 820             current.next = Node
 821             # 将node的prev指向cur
 822             Node.prev = current
 823 
 824     # 指定位置插入元素
 825     def insert(self, pos, item):
 826         if pos <= 0:
 827             self.add(item)
 828         elif pos > (self.length()-1):
 829             self.append(item)
 830         else:
 831             Node = Class_Double_Node(item)
 832             current = self._head
 833             count = 0
 834             # 移动到指定位置的前一个位置
 835             while count < (pos-1):
 836                 count += 1
 837                 current = current.next
 838             # 将node的prev指向cur
 839             Node.prev = current
 840             # 将node的next指向cur的下一个节点
 841             Node.next = current.next
 842             # 将cur的下一个节点的prev指向node
 843             current.next.prev = Node
 844             # 将cur的next指向node
 845             current.next = Node
 846     # 删除元素
 847     def remove(self, item):
 848         """删除元素"""
 849         if self.is_empty():
 850             return
 851         else:
 852             current = self._head
 853             if current.item == item:
 854                 # 如果首节点的元素即是要删除的元素
 855                 if current.next == None:
 856                     # 如果链表只有这一个节点
 857                     self._head = None
 858                 else:
 859                     # 将第二个节点的prev设置为None
 860                     current.next.prev = None
 861                     # 将_head指向第二个节点
 862                     self._head = current.next
 863                 return
 864             while current != None:
 865                 if current.item == item:
 866                     # 将cur的前一个节点的next指向cur的后一个节点
 867                     current.prev.next = current.next
 868                     # 将cur的后一个节点的prev指向cur的前一个节点
 869                     current.next.prev = current.prev
 870                     break
 871                 current = current.next
 872 
 873     # 查找元素是否存在
 874     def search(self, item):
 875         current = self._head
 876         while current != None:
 877             if current.item == item:
 878                 return True
 879             current = current.next
 880         return False
 881     
 882 if __name__ == "__main__":
 883     # 双向链表
 884     single_list_name_C = Class_Double_LinkList()
 885     print("Length:[%s]" % (single_list_name_C.length()))
 886     single_list_name_C.add(111)         # 头部添加元素
 887     single_list_name_C.add(112)         # 头部添加元素
 888     single_list_name_C.add(113)         # 头部添加元素
 889     single_list_name_C.add(114)         # 头部添加元素
 890     single_list_name_C.add(115)         # 头部添加元素
 891     single_list_name_C.append(211)      # 尾部添加元素
 892     single_list_name_C.append(212)      # 尾部添加元素
 893     single_list_name_C.append(213)      # 尾部添加元素
 894     single_list_name_C.travel()         # 遍历链表
 895     print("Length:[%s]" % (single_list_name_C.length()))
 896     single_list_name_C.insert(2, 311)     # 指定位置添加元素
 897     single_list_name_C.insert(4, 312)     # 指定位置添加元素
 898     single_list_name_C.insert(6, 313)     # 指定位置添加元素
 899     print(single_list_name_C.search(111)) # 查找节点是否存在
 900     print(single_list_name_C.search(211)) # 查找节点是否存在
 901     print(single_list_name_C.search(311)) # 查找节点是否存在
 902     single_list_name_C.travel()           # 遍历链表
 903     print("Length:[%s]" % (single_list_name_C.length()))
 904     single_list_name_C.remove(112)
 905     single_list_name_C.remove(113)
 906     single_list_name_C.remove(114)
 907     single_list_name_C.remove(115)
 908     single_list_name_C.remove(211)
 909     single_list_name_C.remove(212)
 910     single_list_name_C.travel()  # 遍历链表
 911     print("Length:[%s]" % (single_list_name_C.length()))
 912     
 913 result:
 914     Length:[0]
 915     Travel  Item : [115]
 916     Travel  Item : [114]
 917     Travel  Item : [113]
 918     Travel  Item : [112]
 919     Travel  Item : [111]
 920     Travel  Item : [211]
 921     Travel  Item : [212]
 922     Travel  Item : [213]
 923     Travel Finish 
 924     Length:[8]
 925     True
 926     True
 927     True
 928     Travel  Item : [115]
 929     Travel  Item : [114]
 930     Travel  Item : [311]
 931     Travel  Item : [113]
 932     Travel  Item : [312]
 933     Travel  Item : [112]
 934     Travel  Item : [313]
 935     Travel  Item : [111]
 936     Travel  Item : [211]
 937     Travel  Item : [212]
 938     Travel  Item : [213]
 939     Travel Finish 
 940     Length:[11]
 941     Travel  Item : [311]
 942     Travel  Item : [312]
 943     Travel  Item : [313]
 944     Travel  Item : [111]
 945     Travel  Item : [213]
 946     Travel Finish 
 947     Length:[5]
 948 
 949 ----------------------------------------------
 950 4. 栈
 951 
 952     栈(stack),有些地方称为堆栈,是一种容器,可存入数据元素、
 953 访问元素、删除元素,它的特点在于只能允许在容器的一端(称为栈顶端
 954 指标,英语:top)进行加入数据(英语:push)和输出数据(英语:
 955 pop)的运算。没有了位置概念,保证任何时候可以访问、删除的元素都
 956 是此前最后存入的那个元素,确定了一种默认的访问顺序。
 957 
 958     由于栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO,
 959 Last In First Out)的原理运作。
 960 
 961 
 962 ----------------------------------------------
 963 5. 队列
 964 
 965     队列(queue)是只允许在一端进行插入操作,而在另一端进行删
 966 除操作的线性表。
 967     队列是一种先进先出的(First In First Out)的线性表,简
 968 称FIFO。允许插入的一端为队尾,允许删除的一端为队头。队列不允许
 969 在中间部位进行操作!假设队列是q=(a1,a2,……,an),那么a1就
 970 是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,
 971 而插入时,总是在队列最后。这也比较符合我们通常生活中的习惯,排在
 972 第一个的优先出列,最后来的当然排在队伍最后。
 973 
 974 -----------------------
 975 5.1 队列的实现
 976 同栈一样,队列也可以用顺序表或者链表实现。
 977 操作
 978     Queue()         创建一个空的队列
 979     enqueue(item)   往队列中添加一个item元素
 980     dequeue()       从队列头部删除一个元素
 981     is_empty()      判断一个队列是否为空
 982     size()          返回队列的大小
 983     
 984 e.g:
 985 # 队列
 986 class Class_Queue(object):
 987     def __init__(self):
 988         self.items = []
 989 
 990     def is_empty(self):
 991         return self.items == []
 992 
 993     # 进队列
 994     def enqueue(self, item):
 995         self.items.insert(0,item)
 996 
 997     # 出队列
 998     def dequeue(self):
 999         return self.items.pop()
1000 
1001     # 大小
1002     def size(self):
1003         return len(self.items)
1004 
1005 if __name__ == "__main__":
1006     # 队列
1007     queue_name_A = Class_Queue()        # 创建对象
1008     queue_name_A.enqueue("hello")       # 进队列
1009     queue_name_A.enqueue("world")       # 进队列
1010     queue_name_A.enqueue("it cast")     # 进队列
1011     print(queue_name_A.size())
1012     queue_name_A.dequeue()              # 出队列
1013     print(queue_name_A.size())
1014     queue_name_A.dequeue()              # 出队列
1015     print(queue_name_A.size())
1016     queue_name_A.dequeue()              # 出队列
1017     print(queue_name_A.size())
1018 result:
1019     3
1020     2
1021     1
1022     0
1023 
1024 -----------------------
1025 5.2 双端队列
1026 
1027     双端队列(Class_Double_Queue,全名double-ended queue),是一种具有
1028 队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定
1029 插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。
1030 
1031 操作
1032     Class_Double_Queue()         创建一个空的双端队列
1033     add_front(item) 从队头加入一个item元素
1034     add_rear(item)  从队尾加入一个item元素
1035     remove_front()  从队头删除一个item元素
1036     remove_rear()   从队尾删除一个item元素
1037     is_empty()      判断双端队列是否为空
1038     size()          返回队列的大小
1039 
1040 e.g:
1041 # 双端队列
1042 # 创建双端队列
1043 class Class_Double_Queue(object):
1044     def __init__(self):
1045         self.items = []
1046 
1047     #判断队列是否为空
1048     def is_empty(self):
1049         return self.items == []
1050 
1051     #在队头添加元素
1052     def add_front(self, item):
1053         self.items.insert(0,item)
1054 
1055     # 在队尾添加元素
1056     def add_rear(self, item):
1057         self.items.append(item)
1058 
1059     #从队头删除元素
1060     def remove_front(self):
1061         return self.items.pop(0)
1062 
1063     #从队尾删除元素
1064     def remove_rear(self):
1065         return self.items.pop()
1066 
1067     #队列大小
1068     def size(self):
1069         return len(self.items)
1070     
1071 if __name__ == "__main__":
1072      Class_Double_Queue = Class_Double_Queue()
1073     Class_Double_Queue.add_front(111)           # 从队头加入一个item元素
1074     Class_Double_Queue.add_front(112)           # 从队头加入一个item元素
1075     Class_Double_Queue.add_rear(213)            # 从队尾加入一个item元素
1076     Class_Double_Queue.add_rear(214)            # 从队尾加入一个item元素
1077     Class_Double_Queue.size()
1078     print(Class_Double_Queue.size())
1079     Class_Double_Queue.remove_front()           # 从队头删除一个item元素
1080     print(Class_Double_Queue.size())
1081     Class_Double_Queue.remove_front()           # 从队头删除一个item元素
1082     print(Class_Double_Queue.size())
1083     Class_Double_Queue.remove_rear()            # 从队尾删除一个item元素
1084     print(Class_Double_Queue.size())
1085     Class_Double_Queue.remove_rear()            # 从队尾删除一个item元素
1086     print(Class_Double_Queue.size())
1087 
1088 result:
1089     4
1090     3
1091     2
1092     1
1093     0
1094     
1095 ----------------------------------------------
1096 6. 排序与搜索
1097 
1098     排序算法(英语:Sorting algorithm)是一种能将一串数据依
1099 照特定顺序进行排列的一种算法。
1100 
1101     排序算法的稳定性。稳定性:稳定排序算法会让原本有相等键值的纪
1102 录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值
1103 的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将
1104 会是在S之前。
1105     当相等的元素是无法分辨的,比如像是整数,稳定性并不是一个问题。
1106 然而,假设以下的数对将要以他们的第一个数字来排序。
1107 (4, 1)  (3, 1)  (3, 7)(5, 6)
1108     在这个状况下,有可能产生两种不同的结果,一个是让相等键值的
1109 纪录维持相对的次序,而另外一个则没有:
1110 (3, 1)  (3, 7)  (4, 1)  (5, 6)  (维持次序)
1111 (3, 7)  (3, 1)  (4, 1)  (5, 6)  (次序被改变)
1112 不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排
1113 序算法从来不会如此。不稳定排序算法可以被特别地实现为稳定。作这件
1114 事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个
1115 对象间之比较,(比如上面的比较中加入第二个标准:第二个键值的大小)
1116 就会被决定使用在原先数据次序中的条目,当作一个同分决赛。然而,要
1117 记住这种次序通常牵涉到额外的空间负担。
1118 
1119 -----------------------
1120 6.1 冒泡排序
1121 
1122     冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复
1123 地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们
1124 交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说
1125 该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换
1126 慢慢“浮”到数列的顶端。
1127 
1128 冒泡排序算法的运作如下:
1129     比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
1130 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步
1131 做完后,最后的元素会是最大的数。针对所有的元素重复以上的步骤,除
1132 了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何
1133 一对数字需要比较。
1134 e.g:
1135 # 冒泡排序
1136 def Function_Algorithm_BubbleSort(alist):
1137     local_var_alist = alist
1138     # print('local_var_alist',local_var_alist)
1139     # range(start,end,scan)
1140     # start:开始 end:结束 scan:步进长度,负为减少+(-X)
1141     for var_A in range(len(local_var_alist)-1,0,-1):
1142         # print("--------------------------")
1143         # print('var_A', var_A)
1144         # var_A表示每次遍历需要比较的次数,是逐渐减小的
1145         for var_B in range(var_A):
1146             # print('var_B', var_B)
1147             # print(local_var_alist[var_B], local_var_alist[var_B + 1])
1148             if local_var_alist[var_B] > local_var_alist[var_B + 1]:
1149                 ### 二个数据交换,以下三步用一个表达式代替
1150                 # # var_name = local_var_alist[var_B]
1151                 # # local_var_alist[var_B] = local_var_alist[var_B + 1]
1152                 # # local_var_alist[var_B + 1] = var_name
1153                 local_var_alist[var_B], local_var_alist[var_B+1] = local_var_alist[var_B+1], local_var_alist[var_B]
1154 
1155 if __name__ == "__main__":
1156     BubbleSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20]
1157     print("P",BubbleSort_name_A)    # 前
1158     Function_Algorithm_BubbleSort(BubbleSort_name_A)
1159     print("N",BubbleSort_name_A)    # 后
1160 result:
1161     P [54, 26, 93, 17, 77, 31, 44, 55, 20]
1162     N [17, 20, 26, 31, 44, 54, 55, 77, 93]
1163 
1164 最优时间复杂度:O(n) (表示遍历一次发现没有任何可以交换的元素,排序结束。)
1165 最坏时间复杂度:O(n2)
1166 稳定性:稳定
1167 
1168 
1169 -----------------------
1170 6.2 选择排序
1171 
1172     选择排序(Selection sort)是一种简单直观的排序算法。它的
1173 工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序
1174 列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,
1175 然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
1176     选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终
1177 位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有
1178 一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多
1179 n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序
1180 属于非常好的一种。
1181 
1182 e.g:
1183 # 选择排序
1184 def Function_Algorithm_SelectionSort(alist):
1185     local_var_alist = alist
1186 
1187     number = len(local_var_alist)
1188     # 需要进行n-1次选择操作
1189     for var_A in range(number-1):
1190         # print("--------------------------")
1191         min_index = var_A   # 记录最小位置
1192         # print('var_A: ', var_A, " --- min_index : ", min_index)
1193         # 从i+1位置到末尾选择出最小数据
1194         for var_B in range(var_A+1, number):
1195             # print("var_B:(%s)  | var_A:(%s)  | number:(%s)"%(var_B,var_A+1,number))
1196             # print(local_var_alist[var_B],local_var_alist[min_index])
1197 
1198             if local_var_alist[var_B] < local_var_alist[min_index]:
1199                 min_index = var_B
1200                 # print(local_var_alist[var_B], local_var_alist[min_index])
1201         # 如果选择出的数据不在正确位置,进行交换
1202         if min_index != var_A:
1203             local_var_alist[var_A], local_var_alist[min_index] = local_var_alist[min_index], local_var_alist[var_A]
1204             # print(">>",local_var_alist[var_A],local_var_alist[min_index])
1205 
1206 if __name__ == "__main__":
1207     SelectionSort_name_A = [54, 226, 93, 17, 77, 31, 44, 55, 20]
1208     print("P",SelectionSort_name_A)
1209     Function_Algorithm_SelectionSort(SelectionSort_name_A)
1210     print("N",SelectionSort_name_A)
1211     
1212 result:
1213     P [54, 226, 93, 17, 77, 31, 44, 55, 20]
1214     N [17, 20, 31, 44, 54, 55, 77, 93, 226]
1215     
1216 时间复杂度
1217 最优时间复杂度:O(n2)
1218 最坏时间复杂度:O(n2)
1219 稳定性:不稳定(考虑升序每次选择最大的情况)
1220 
1221 -----------------------
1222 6.3 插入排序
1223     插入排序(英语:Insertion Sort)是一种简单直观的排序算法。
1224 它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从
1225 后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描
1226 过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
1227 
1228 
1229 
1230 e.g:
1231 def Function_Algorithm_InsertSort(alist):
1232     local_var_alist = alist
1233     # 从第二个位置,即下标为1的元素开始向前插入
1234     for var_A in range(1, len(local_var_alist)):
1235         # 从第i个元素开始向前比较,如果小于前一个元素,交换位置
1236         for var_B in range(var_A, 0, -1):
1237             if local_var_alist[var_B] < local_var_alist[var_B-1]:
1238                 local_var_alist[var_B], local_var_alist[var_B-1] = local_var_alist[var_B-1], local_var_alist[var_B]
1239 
1240 if __name__ == "__main__":
1241     InsertionSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20]
1242     print("P",InsertionSort_name_A)
1243     Function_Algorithm_InsertSort(InsertionSort_name_A)
1244     print("N",InsertionSort_name_A)
1245 result:
1246     P [54, 26, 93, 17, 77, 31, 44, 55, 20]
1247     N [17, 20, 26, 31, 44, 54, 55, 77, 93]
1248 
1249 时间复杂度
1250 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
1251 最坏时间复杂度:O(n2)
1252 稳定性:稳定
1253 
1254 -----------------------
1255 6.4 快速排序
1256 
1257     快速排序(英语:Quicksort),又称划分交换排序(partition
1258 -exchange sort),通过一趟排序将要排序的数据分割成独立的两
1259 部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后
1260 再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归
1261 进行,以此达到整个数据变成有序序列。
1262 
1263 步骤为:
1264 1)从数列中挑出一个元素,称为"基准"(pivot),
1265 2)重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基
1266 准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之
1267 后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
1268 3)递归地(recursive)把小于基准值元素的子数列和大于基准值元素
1269 的子数列排序。
1270     递归的最底部情形,是数列的大小是零或一,也就是永远都已经被
1271 排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的
1272 迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
1273 
1274 e.g:
1275 # 快速排序
1276 #
1277 def Function_Algorithm_QuickSort(alist, start, end):
1278     """快速排序"""
1279     local_var_alist = alist
1280     local_var_start = start
1281     local_var_end   = end
1282 
1283     # 递归的退出条件
1284     if local_var_start >= local_var_end:
1285         return
1286 
1287     # 设定起始元素为要寻找位置的基准元素
1288     list_mid = local_var_alist[local_var_start]
1289     # low为序列左边的由左向右移动的游标
1290     list_low = local_var_start
1291     # high为序列右边的由右向左移动的游标
1292     list_high = local_var_end
1293 
1294     print("1 >>",list_low,list_mid,list_high)
1295 
1296     while list_low < list_high:
1297         print("L H",list_low,list_high)
1298         # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
1299         while list_low < list_high and local_var_alist[list_high] >= list_mid:
1300             list_high -= 1
1301         # 将high指向的元素放到low的位置上
1302         local_var_alist[list_low] = local_var_alist[list_high]
1303         print("2 >>", local_var_alist[list_low] )
1304         # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
1305         while list_low < list_high and local_var_alist[list_low] < list_mid:
1306             list_low += 1
1307         # 将low指向的元素放到high的位置上
1308         local_var_alist[list_high] = local_var_alist[list_low]
1309         print("3 >>", local_var_alist[list_high])
1310         print("----------")
1311     # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
1312     # 将基准元素放到该位置
1313 
1314     local_var_alist[list_low] = list_mid
1315     print("4 >>", local_var_alist[list_low])
1316     print("==================")
1317     # # 对基准元素左边的子序列进行快速排序
1318     Function_Algorithm_QuickSort(local_var_alist, local_var_start, list_low-1)
1319     #
1320     # # 对基准元素右边的子序列进行快速排序
1321     Function_Algorithm_QuickSort(local_var_alist, list_low+1, local_var_end)
1322 
1323 
1324 if __name__ == "__main__":
1325     QuickSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20]
1326     print("P", QuickSort_name_A)
1327     Function_Algorithm_QuickSort(QuickSort_name_A, 0, len(QuickSort_name_A) - 1)
1328     print("N", QuickSort_name_A)
1329 result:
1330     P [54, 26, 93, 17, 77, 31, 44, 55, 20]
1331     1 >> 0 54 8
1332     L H 0 8
1333     2 >> 20
1334     3 >> 93
1335     ----------
1336     L H 2 8
1337     2 >> 44
1338     3 >> 77
1339     ----------
1340     L H 4 6
1341     2 >> 31
1342     3 >> 31
1343     ----------
1344     4 >> 54
1345     ==================
1346     1 >> 0 20 4
1347     L H 0 4
1348     2 >> 17
1349     3 >> 26
1350     ----------
1351     L H 1 3
1352     2 >> 26
1353     3 >> 26
1354     ----------
1355     4 >> 20
1356     ==================
1357     1 >> 2 44 4
1358     L H 2 4
1359     2 >> 31
1360     3 >> 31
1361     ----------
1362     4 >> 44
1363     ==================
1364     1 >> 2 31 3
1365     L H 2 3
1366     2 >> 26
1367     3 >> 26
1368     ----------
1369     4 >> 31
1370     ==================
1371     1 >> 6 77 8
1372     L H 6 8
1373     2 >> 55
1374     3 >> 55
1375     ----------
1376     4 >> 77
1377     ==================
1378     N [17, 20, 26, 31, 44, 54, 55, 77, 93]
1379     
1380 时间复杂度
1381 最优时间复杂度:O(nlogn)
1382 最坏时间复杂度:O(n2)
1383 稳定性:不稳定
1384     从一开始快速排序平均需要花费O(n log n)时间的描述并不明显。
1385 但是不难观察到的是分区运算,数组的元素都会在每次循环中走访过一次,
1386 使用O(n)的时间。在使用结合(concatenation)的版本中,这项运
1387 算也是O(n)。
1388     在最好的情况,每次我们运行一次分区,我们会把一个数列分为两
1389 个几近相等的片段。这个意思就是每次递归调用处理一半大小的数列。
1390 因此,在到达大小为一的数列前,我们只要作log n次嵌套的调用。这
1391 个意思就是调用树的深度是O(log n)。但是在同一层次结构的两个程
1392 序调用中,不会处理到原来数列的相同部分;因此,程序调用的每一层
1393 次结构总共全部仅需要O(n)的时间(每个调用有某些共同的额外耗费,
1394 但是因为在每一层次结构仅仅只有O(n)个调用,这些被归纳在O(n)系
1395 数中)。结果是这个算法仅需使用O(n log n)时间。
1396 -----------------------
1397 6.5 希尔排序
1398 
1399     希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,
1400 是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算
1401 法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按
1402 下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐
1403 减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成
1404 一组,算法便终止。
1405 
1406 希尔排序过程
1407     希尔排序的基本思想是:将数组列在一个表中并对列分别进行插入
1408 排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来
1409 进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算
1410 法,算法本身还是使用数组进行排序。
1411 
1412 例如,假设有这样一组数
1413 [ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],
1414 如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表
1415 中来更好地描述算法,这样他们就应该看起来是这样(竖着的元素是步长组
1416 成):
1417 13 14 94 33 82
1418 25 59 94 65 23
1419 45 27 73 25 39
1420 10
1421 然后我们对每列进行排序:
1422 10 14 73 25 23
1423 13 27 94 33 39
1424 25 59 94 65 82
1425 45
1426 
1427 将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 
1428 27 94 33 39 25 59 94 65 82 45 ]。这时10已经移至正确位置
1429 了,然后再以3为步长进行排序:
1430 10 14 73
1431 25 23 13
1432 27 94 33
1433 39 25 59
1434 94 65 82
1435 45
1436 排序之后变为:
1437 10 14 13
1438 25 23 33
1439 27 25 59
1440 39 65 73
1441 45 94 82
1442 94
1443 最后以1步长进行排序(此时就是简单的插入排序了)
1444 
1445 e.g:
1446     # 希尔排序
1447 def Function_Algorithm_ShellSort(alist):
1448     n = len(alist)
1449     # 初始步长
1450     var = n / 2
1451     gap = int(var)
1452     print(gap,type(gap))
1453     while gap > 0:
1454         # 按步长进行插入排序
1455         for i in range(gap, n):
1456             j = i
1457             # 插入排序
1458             while j>=gap and alist[j-gap] > alist[j]:
1459                 alist[j-gap], alist[j] = alist[j], alist[j-gap]
1460                 j -= gap
1461         # 得到新的步长
1462         gap = gap / 2
1463 
1464 
1465 if __name__ == "__main__":
1466     ShellSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20, 99]
1467     print(ShellSort_name_A)
1468     Function_Algorithm_ShellSort(ShellSort_name_A)
1469     print(ShellSort_name_A)
1470 result:
1471 时间复杂度
1472 最优时间复杂度:根据步长序列的不同而不同
1473 最坏时间复杂度:O(n2)
1474 稳定想:不稳定
1475 -----------------------
1476 6.6 归并排序
1477 
1478     归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是
1479 先递归分解数组,再合并数组。将数组分解最小之后,然后合并两个有序
1480 数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相
1481 应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个
1482 数组的剩余部分复制过来即可。
1483 
1484 e.g:
1485 
1486 if __name__ == "__main__":
1487 
1488 result:
1489 
1490 
1491 -----------------------
1492 
1493 
1494 -----------------------
1495 6.8 搜索
1496 
1497 搜索是在一个项目集合中找到一个特定项目的算法过程。搜索通常的答案
1498 是真的或假的,因为该项目是否存在。 搜索的几种常见方法:顺序查找、
1499 二分法查找、二叉树查找、哈希查找
1500 
1501 二分法查找
1502 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;
1503 其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法
1504 适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升
1505 序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,
1506 则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中
1507 间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进
1508 一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找
1509 成功,或直到子表不存在为止,此时查找不成功。
1510 e.g:
1511 # 非递归实现
1512 def binary_search(alist, item):
1513       first = 0
1514       last = len(alist)-1
1515       while first<=last:
1516           midpoint = (first + last)/2
1517           if alist[midpoint] == item:
1518               return True
1519           elif item < alist[midpoint]:
1520               last = midpoint-1
1521           else:
1522               first = midpoint+1
1523     return False
1524 
1525 # 递归实现
1526 def binary_search(alist, item):
1527     if len(alist) == 0:
1528         return False
1529     else:
1530         midpoint = len(alist)//2
1531         if alist[midpoint]==item:
1532           return True
1533         else:
1534           if item<alist[midpoint]:
1535             return binary_search(alist[:midpoint],item)
1536           else:
1537             return binary_search(alist[midpoint+1:],item)
1538 
1539 
1540 if __name__ == "__main__":
1541     #------------------------------------
1542     testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
1543     print(binary_search(testlist, 3))
1544     print(binary_search(testlist, 13))
1545     #------------------------------------
1546     testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
1547     print(binary_search(testlist, 3))
1548     print(binary_search(testlist, 13))
1549     
1550     
1551 result:
1552 
1553 ----------------------------------------------
1554 7. 树与树算法
1555 
1556 树的概念
1557     树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象
1558 数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由
1559 n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是
1560 因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它
1561 具有以下的特点:
1562 *每个节点有零个或多个子节点;
1563 *没有父节点的节点称为根节点;
1564 *每一个非根节点有且只有一个父节点;
1565 *除了根节点外,每个子节点可以分为多个不相交的子树;
1566 比如说:
1567 tree Treedatastructure
1568 
1569 树的术语
1570     节点的度:一个节点含有的子树的个数称为该节点的度;
1571     树的度:一棵树中,最大的节点的度称为树的度;
1572     叶节点或终端节点:度为零的节点;
1573     父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
1574     孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
1575     兄弟节点:具有相同父节点的节点互称为兄弟节点;
1576     节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
1577     树的高度或深度:树中节点的最大层次;
1578     堂兄弟节点:父节点在同一层的节点互为堂兄弟;
1579     节点的祖先:从根到该节点所经分支上的所有节点;
1580     子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
1581     森林:由m(m>=0)棵互不相交的树的集合称为森林;
1582 树的种类
1583     无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树;
1584     有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树;
1585     二叉树:每个节点最多含有两个子树的树称为二叉树;
1586     完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层
1587 外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地
1588 紧密排列,这样的二叉树被称为完全二叉树,其中满二叉树的定义是所有
1589 叶节点都在最底层的完全二叉树;
1590     平衡二叉树(AVL树):当且仅当任何节点的两棵子树的高度差不大于1的二叉树;
1591     排序二叉树(二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树);
1592     霍夫曼树(用于信息编码):带权路径最短的二叉树称为哈夫曼树或最优二叉树;
1593     B树:一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多余两个子树。
1594 树的存储与表示
1595     顺序存储:将数据结构存储在固定的数组中,然在遍历速度上有一
1596 定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储。
1597 
1598     树的顺序存储。链式存储和树的链式存储
1599 
1600     由于对节点的个数无法掌握,常见树的存储表示都转换成二叉树进行
1601 处理,子节点个数最多为2
1602 
1603 常见的一些树的应用场景
1604 1.xml,html等,那么编写这些东西的解析器的时候,不可避免用到树
1605 2.路由协议就是使用了树的算法
1606 3.mysql数据库索引
1607 4.文件系统的目录结构
1608 5.所以很多经典的AI算法其实都是树搜索,此外机器学习中的decision tree也是树结构
1609 
1610 
1611 -----------------------
1612 7.1 二叉树
1613 
1614 二叉树的基本概念
1615     二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子
1616 树”(left subtree)和“右子树”(right subtree)
1617 
1618 二叉树的性质(特性)
1619 性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)
1620 性质2: 深度为k的二叉树至多有2^k - 1个结点(k>0)
1621 性质3: 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
1622 性质4:具有n个结点的完全二叉树的深度必为 log2(n+1)
1623 性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,
1624      其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必
1625      为i/2(i=1 时为根,除外)
1626 
1627 (1)完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 
1628 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子
1629 结点都是从左到右依次排布,这就是完全二叉树。
1630 
1631 完全二叉树
1632 (2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处
1633 在最底层的二叉树。
1634 
1635 满二叉树
1636 
1637 二叉树的节点表示以及树的创建
1638     通过使用Node类中定义三个属性,分别为elem本身的值,还
1639 有lchild左孩子和rchild右孩子
1640 
1641 class Node(object):
1642     """节点类"""
1643     def __init__(self, elem=-1, lchild=None, rchild=None):
1644         self.elem = elem
1645         self.lchild = lchild
1646         self.rchild = rchild
1647 树的创建,创建一个树的类,并给一个root根节点,一开始为空,随后添加节点
1648 
1649 class Tree(object):
1650     """树类"""
1651     def __init__(self, root=None):
1652         self.root = root
1653 
1654     def add(self, elem):
1655         """为树添加节点"""
1656         node = Node(elem)
1657         #如果树是空的,则对根节点赋值
1658         if self.root == None:
1659             self.root = node
1660         else:
1661             queue = []
1662             queue.append(self.root)
1663             #对已有的节点进行层次遍历
1664             while queue:
1665                 #弹出队列的第一个元素
1666                 cur = queue.pop(0)
1667                 if cur.lchild == None:
1668                     cur.lchild = node
1669                     return
1670                 elif cur.rchild == None:
1671                     cur.rchild = node
1672                     return
1673                 else:
1674                     #如果左右子树都不为空,加入队列继续判断
1675                     queue.append(cur.lchild)
1676                     queue.append(cur.rchild)
1677 e.g:
1678 
1679 if __name__ == "__main__":
1680 
1681 result:
1682 
1683 -----------------------
1684 7.2 二叉树的遍历
1685 
1686     树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信
1687 息的访问,即依次对树中每个结点访问一次且仅访问一次,我们把这种对
1688 所有节点的访问称为遍历(traversal)。那么树的两种重要的遍历模式
1689 是深度优先遍历和广度优先遍历,深度优先一般用递归,广度优先一般用
1690 队列。一般情况下能用递归实现的算法大部分也能用堆栈来实现。
1691 
1692 深度优先遍历
1693     对于一颗二叉树,深度优先搜索(Depth First Search)是沿着
1694 树的深度遍历树的节点,尽可能深的搜索树的分支。那么深度遍历有重要
1695 的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访
1696 问每个节点的次序不同。这三种遍历分别叫做先序遍历(preorder),
1697 中序遍历(inorder)和后序遍历(postorder)。我们来给出它们的
1698 详细定义,然后举例看看它们的应用。
1699 
1700 先序遍历 在先序遍历中,我们先访问根节点,然后递归使用先序遍历访
1701 问左子树,再递归使用先序遍历访问右子树
1702 
1703 根节点->左子树->右子树
1704 def preorder(self, root):
1705       """递归实现先序遍历"""
1706       if root == None:
1707           return
1708       print root.elem
1709       self.preorder(root.lchild)
1710       self.preorder(root.rchild)
1711 中序遍历 在中序遍历中,我们递归使用中序遍历访问左子树,然后访问
1712 根节点,最后再递归使用中序遍历访问右子树
1713 
1714 左子树->根节点->右子树
1715 def inorder(self, root):
1716       """递归实现中序遍历"""
1717       if root == None:
1718           return
1719       self.inorder(root.lchild)
1720       print root.elem
1721       self.inorder(root.rchild)
1722 后序遍历 在后序遍历中,我们先递归使用后序遍历访问左子树和右子树,
1723 最后访问根节点。
1724 
1725 左子树->右子树->根节点
1726 def postorder(self, root):
1727       """递归实现后续遍历"""
1728       if root == None:
1729           return
1730       self.postorder(root.lchild)
1731       self.postorder(root.rchild)
1732       print root.elem
1733       
1734 三种遍历结果
1735 课堂练习: 按照如图树的结构写出三种遍历的顺序:
1736 树练习
1737 结果:
1738 先序:a b c d e f g h
1739 中序:b d c e a f h g
1740 后序:d e c b h g f a
1741 思考:哪两种遍历方式能够唯一的确定一颗树???
1742 
1743 广度优先遍历(层次遍历)
1744 从树的root开始,从上到下从从左到右遍历整个树的节点
1745 
1746 def breadth_travel(self, root):
1747         """利用队列实现树的层次遍历"""
1748         if root == None:
1749             return
1750         queue = []
1751         queue.append(root)
1752         while queue:
1753             node = queue.pop(0)
1754             print node.elem,
1755             if node.lchild != None:
1756                 queue.append(node.lchild)
1757             if node.rchild != None:
1758                 queue.append(node.rchild)
1759 e.g:
1760 
1761 if __name__ == "__main__":
1762 
1763 result:
1764 
1765 ----------------------------------------------
1766 
1767 ============================================================================
1768 '''
1769 #
1770 
1771 
1772 
1773 #
1774 '''
1775 # ============================================================================
1776 # Function:  
1777 # Explain :  输入参数   
1778 #         :  输出参数  
1779 # ============================================================================
1780 '''
1781 
1782 #-----------------------
1783 # 1.7 list的操作测试
1784 
1785 def Function_Test_A():
1786     l = []
1787     for i in range(1000):
1788         l = l + [i]
1789 
1790 def Function_Test_B():
1791     l = []
1792     for i in range(1000):
1793         l.append(i)
1794 
1795 def Function_Test_C():
1796     l = [i for i in range(1000)]
1797 
1798 def Function_Test_D():
1799     l = list(range(1000))
1800 
1801 #-----------------------
1802 # 单链表
1803 #节点实现创建
1804 class Class_Single_Node(object):
1805     # 单链表的结点
1806     def __init__(self,item):
1807         # _item存放数据元素
1808         self.item = item
1809         # _next是下一个节点的标识
1810         self.next = None
1811 
1812 #单链表的操作实现
1813 class SingleLinkList(object):
1814     # 单链表头文件
1815     def __init__(self):
1816         self._head = None
1817 
1818     # 判断链表是否为空
1819     def is_empty(self):
1820         return self._head == None
1821 
1822     # 链表长度
1823     def length(self):
1824         # cur初始时指向头节点
1825         current = self._head
1826         count = 0
1827         # 尾节点指向None,当未到达尾部时
1828         while current != None:
1829             count  += 1
1830             current = current.next # 将cur后移一个节点
1831         return count
1832 
1833     # 遍历链表
1834     def travel(self):
1835         current = self._head
1836         while current != None:
1837             print ("Travel  Item : [%s]"%(current.item))
1838             current = current.next
1839         print ("Current Item : (%s)" % (current))
1840 
1841     # 头部添加元素
1842     def add(self, item):
1843         # 先创建一个保存item值的节点 这是创建的前提条件
1844         Node = Class_Single_Node(item)
1845         # 将新节点的链接域next指向头节点,即_head指向的位置
1846         Node.next = self._head
1847         # 将链表的头_head指向新节点
1848         self._head = Node
1849 
1850     # 尾部添加元素
1851     def append(self, item):
1852         Node = Class_Single_Node(item)
1853         # 先判断链表是否为空,若是空链表,则将_head指向新节点
1854         if self.is_empty():
1855             self._head = Node
1856         # 若不为空,则找到尾部,将尾节点的next指向新节点
1857         else:
1858             current = self._head
1859             while current.next != None:
1860                 current = current.next
1861             current.next = Node
1862 
1863     # 指定位置添加元素
1864     def insert(self, pos, item):
1865         # 若指定位置pos为第一个元素之前,则执行头部插入
1866         if pos <= 0:
1867             self.add(item)
1868         # 若指定位置超过链表尾部,则执行尾部插入
1869         elif pos > (self.length()-1):
1870             self.append(item)
1871         # 找到指定位置
1872         else:
1873             Node = Class_Single_Node(item)  # 创建新的列表
1874             count = 0
1875             # pre用来指向指定位置pos的前一个位置pos-1,初始从头节点开始移动到指定位置
1876             previous = self._head
1877             while count < (pos-1):
1878                 count += 1
1879                 previous = previous.next
1880             # 先将新节点node的next指向插入位置的节点
1881             Node.next = previous.next
1882             # 将插入位置的前一个节点的next指向新节点
1883             previous.next = Node
1884 
1885     # 删除节点
1886     def remove(self,item):
1887         current = self._head
1888         previous = None
1889         while current != None:
1890             # 找到了指定元素
1891             if current.item == item:
1892                 # 如果第一个就是删除的节点
1893                 if not previous:
1894                     # 将头指针指向头节点的后一个节点
1895                     self._head = current.next
1896                 else:
1897                     # 将删除位置前一个节点的next指向删除位置的后一个节点
1898                     previous.next = current.next
1899                 break
1900             else:
1901                 # 继续按链表后移节点
1902                 previous = current
1903                 current = current.next
1904 
1905     #查找节点是否存在
1906     def search(self,item):
1907         # 表查找节点是否存在,并返回True或者False
1908         current = self._head
1909         while current != None:
1910             if current.item == item:
1911                 return True
1912             current = current.next
1913         return False
1914 
1915 #-----------------------
1916 # 单向循环链表
1917 # 单项节点创建 class Class_Single_Node(object):
1918 
1919 class Class_SinCyc_Linkedlist(object):
1920     def __init__(self):
1921         self._head = None
1922 
1923     # 判断链表是否为空
1924     def is_empty(self):
1925         return self._head == None
1926 
1927     # 返回链表的长度
1928     def length(self):
1929         # 如果链表为空,返回长度0
1930         if self.is_empty():
1931             return 0
1932         count = 1
1933         current = self._head
1934         while current.next != self._head:
1935             count += 1
1936             current = current.next
1937         return count
1938 
1939     # 遍历链表
1940     def travel(self):
1941         # 判断是否为空
1942         if self.is_empty():
1943             return
1944         current = self._head
1945         print("Travel  Item : [%s]" % (current.item))
1946         while current.next != self._head:
1947             current = current.next
1948             print("Travel  Item : [%s]" % (current.item))
1949         print("Travel Finish ")
1950 
1951     # 头部添加节点
1952     def add(self, item):
1953         Node = Class_Single_Node(item)
1954         # 判断是否为空
1955         if self.is_empty():
1956             self._head = Node
1957             Node.next = self._head
1958         else:
1959             #添加的节点指向_head
1960             Node.next = self._head
1961             # 移到链表尾部,将尾部节点的next指向node
1962             current = self._head
1963             while current.next != self._head:
1964                 current = current.next
1965             current.next = Node
1966             #_head指向添加node的
1967             self._head = Node
1968     # 尾部添加节点
1969     def append(self, item):
1970         Node = Class_Single_Node(item)
1971         if self.is_empty():
1972             self._head = Node
1973             Node.next = self._head
1974         else:
1975             # 移到链表尾部
1976             current = self._head
1977             while current.next != self._head:
1978                 current = current.next
1979             # 将尾节点指向node
1980             current.next = Node
1981             # 将node指向头节点_head
1982             Node.next = self._head
1983     # 指定位置添加节点
1984     def insert(self, pos, item):
1985         if pos <= 0:
1986             self.add(item)
1987         elif pos > (self.length()-1):
1988             self.append(item)
1989         else:
1990             Node = Class_Single_Node(item)
1991             current = self._head
1992             count = 0
1993             # 移动到指定位置的前一个位置
1994             while count < (pos-1):
1995                 count += 1
1996                 current = current.next
1997             Node.next = current.next
1998             current.next = Node
1999 
2000     def remove(self, item):
2001         """删除一个节点"""
2002         # 若链表为空,则直接返回
2003         if self.is_empty():
2004             return
2005         # 将cur指向头节点
2006         current = self._head
2007         pre = None
2008         # 若头节点的元素就是要查找的元素item
2009         if current.item == item:
2010             # 如果链表不止一个节点
2011             if current.next != self._head:
2012                 # 先找到尾节点,将尾节点的next指向第二个节点
2013                 while current.next != self._head:
2014                     current = current.next
2015                 # cur指向了尾节点
2016                 current.next = self._head.next
2017                 self._head = self._head.next
2018             else:
2019                 # 链表只有一个节点
2020                 self._head = None
2021         else:
2022             pre = self._head
2023             # 第一个节点不是要删除的
2024             while current.next != self._head:
2025                 # 找到了要删除的元素
2026                 if current.item == item:
2027                     # 删除
2028                     pre.next = current.next
2029                     return
2030                 else:
2031                     pre = current
2032                     current = current.next
2033             # current 指向尾节点
2034             if current.item == item:
2035                 # 尾部删除
2036                 pre.next = current.next
2037     # 查找节点是否存在
2038     def search(self, item):
2039         if self.is_empty():
2040             return False
2041         current = self._head
2042         if current.item == item:
2043             return True
2044         while current.next != self._head:
2045             current = current.next
2046             if current.item == item:
2047                 return True
2048         return False
2049 
2050 #-----------------------
2051 # 双向链表
2052 
2053 # 双向链表节点
2054 class Class_Double_Node(object):
2055     def __init__(self, item):
2056         # _item存放数据元素
2057         self.item = item
2058         # _next是下一个节点的标识
2059         self.next = None
2060         # _prev是上一个节点的标识
2061         self.prev = None
2062 
2063 # 双向链表操作
2064 class Class_Double_LinkList(object):
2065     def __init__(self):
2066         self._head = None
2067 
2068     # 判断链表是否为空
2069     def is_empty(self):
2070         return self._head == None
2071     
2072     # 链表的长度
2073     def length(self):
2074         current = self._head
2075         count = 0
2076         while current != None:
2077             count += 1
2078             current = current.next
2079         return count
2080     
2081     # 遍历链表
2082     def travel(self):
2083         current = self._head
2084         while current != None:
2085             print("Travel  Item : [%s]" % (current.item))
2086             current = current.next
2087         print("Travel Finish ")
2088     
2089     # 头部插入元素
2090     def add(self, item):
2091         Node = Class_Double_Node(item)
2092         # 如果是空链表,将_head指向node
2093         if self.is_empty():
2094             self._head = Node
2095         else:
2096             # 将node的next指向_head的头节点
2097             Node.next = self._head
2098             # 将_head的头节点的prev指向node
2099             self._head.prev = Node
2100             # 将_head 指向node
2101             self._head = Node
2102 
2103     # 尾部插入元素
2104     def append(self, item):
2105         Node = Class_Double_Node(item)
2106         # 如果是空链表,将_head指向node
2107         if self.is_empty():
2108             self._head = Node
2109         else:
2110             # 移动到链表尾部
2111             current = self._head
2112             while current.next != None:
2113                 current = current.next
2114             # 将尾节点cur的next指向node
2115             current.next = Node
2116             # 将node的prev指向cur
2117             Node.prev = current
2118 
2119     # 指定位置插入元素
2120     def insert(self, pos, item):
2121         if pos <= 0:
2122             self.add(item)
2123         elif pos > (self.length()-1):
2124             self.append(item)
2125         else:
2126             Node = Class_Double_Node(item)
2127             current = self._head
2128             count = 0
2129             # 移动到指定位置的前一个位置
2130             while count < (pos-1):
2131                 count += 1
2132                 current = current.next
2133             # 将node的prev指向cur
2134             Node.prev = current
2135             # 将node的next指向cur的下一个节点
2136             Node.next = current.next
2137             # 将cur的下一个节点的prev指向node
2138             current.next.prev = Node
2139             # 将cur的next指向node
2140             current.next = Node
2141     # 删除元素
2142     def remove(self, item):
2143         """删除元素"""
2144         if self.is_empty():
2145             return
2146         else:
2147             current = self._head
2148             if current.item == item:
2149                 # 如果首节点的元素即是要删除的元素
2150                 if current.next == None:
2151                     # 如果链表只有这一个节点
2152                     self._head = None
2153                 else:
2154                     # 将第二个节点的prev设置为None
2155                     current.next.prev = None
2156                     # 将_head指向第二个节点
2157                     self._head = current.next
2158                 return
2159             while current != None:
2160                 if current.item == item:
2161                     # 将cur的前一个节点的next指向cur的后一个节点
2162                     current.prev.next = current.next
2163                     # 将cur的后一个节点的prev指向cur的前一个节点
2164                     current.next.prev = current.prev
2165                     break
2166                 current = current.next
2167 
2168     # 查找元素是否存在
2169     def search(self, item):
2170         current = self._head
2171         while current != None:
2172             if current.item == item:
2173                 return True
2174             current = current.next
2175         return False
2176 
2177 #-----------------------
2178 # 队列
2179 class Class_Queue(object):
2180     def __init__(self):
2181         self.items = []
2182 
2183     def is_empty(self):
2184         return self.items == []
2185 
2186     # 进队列
2187     def enqueue(self, item):
2188         self.items.insert(0,item)
2189 
2190     # 出队列
2191     def dequeue(self):
2192         return self.items.pop()
2193 
2194     # 大小
2195     def size(self):
2196         return len(self.items)
2197 
2198 #-----------------------
2199 # 双端队列
2200 # 创建双端队列
2201 class Class_Double_Queue(object):
2202     def __init__(self):
2203         self.items = []
2204 
2205     #判断队列是否为空
2206     def is_empty(self):
2207         return self.items == []
2208 
2209     #在队头添加元素
2210     def add_front(self, item):
2211         self.items.insert(0,item)
2212 
2213     # 在队尾添加元素
2214     def add_rear(self, item):
2215         self.items.append(item)
2216 
2217     #从队头删除元素
2218     def remove_front(self):
2219         return self.items.pop(0)
2220 
2221     #从队尾删除元素
2222     def remove_rear(self):
2223         return self.items.pop()
2224 
2225     #队列大小
2226     def size(self):
2227         return len(self.items)
2228     
2229 #-----------------------
2230 # 冒泡排序
2231 def Function_Algorithm_BubbleSort(alist):
2232     local_var_alist = alist
2233     # print('local_var_alist',local_var_alist)
2234     # range(start,end,scan)
2235     # start:开始 end:结束 scan:步进长度,负为减少+(-X)
2236     for var_A in range(len(local_var_alist)-1,0,-1):
2237         # print("--------------------------")
2238         # print('var_A', var_A)
2239         # var_A表示每次遍历需要比较的次数,是逐渐减小的
2240         for var_B in range(var_A):
2241             # print('var_B', var_B)
2242             # print(local_var_alist[var_B], local_var_alist[var_B + 1])
2243             if local_var_alist[var_B] > local_var_alist[var_B + 1]:
2244                 ### 二个数据交换,以下三步用一个表达式代替
2245                 # # var_name = local_var_alist[var_B]
2246                 # # local_var_alist[var_B] = local_var_alist[var_B + 1]
2247                 # # local_var_alist[var_B + 1] = var_name
2248                 local_var_alist[var_B], local_var_alist[var_B+1] = local_var_alist[var_B+1], local_var_alist[var_B]
2249 
2250 #-----------------------
2251 # 选择排序
2252 def Function_Algorithm_SelectionSort(alist):
2253     local_var_alist = alist
2254 
2255     number = len(local_var_alist)
2256     # 需要进行n-1次选择操作
2257     for var_A in range(number-1):
2258         # print("--------------------------")
2259         min_index = var_A   # 记录最小位置
2260         # print('var_A: ', var_A, " --- min_index : ", min_index)
2261         # 从i+1位置到末尾选择出最小数据
2262         for var_B in range(var_A+1, number):
2263             # print("var_B:(%s)  | var_A:(%s)  | number:(%s)"%(var_B,var_A+1,number))
2264             # print(local_var_alist[var_B],local_var_alist[min_index])
2265 
2266             if local_var_alist[var_B] < local_var_alist[min_index]:
2267                 min_index = var_B
2268                 # print(local_var_alist[var_B], local_var_alist[min_index])
2269         # 如果选择出的数据不在正确位置,进行交换
2270         if min_index != var_A:
2271             local_var_alist[var_A], local_var_alist[min_index] = local_var_alist[min_index], local_var_alist[var_A]
2272             # print(">>",local_var_alist[var_A],local_var_alist[min_index])
2273 
2274 #-----------------------
2275 # 插入排序
2276 def Function_Algorithm_InsertSort(alist):
2277     local_var_alist = alist
2278     # 从第二个位置,即下标为1的元素开始向前插入
2279     for var_A in range(1, len(local_var_alist)):
2280         # 从第i个元素开始向前比较,如果小于前一个元素,交换位置
2281         for var_B in range(var_A, 0, -1):
2282             if local_var_alist[var_B] < local_var_alist[var_B-1]:
2283                 local_var_alist[var_B], local_var_alist[var_B-1] = local_var_alist[var_B-1], local_var_alist[var_B]
2284 
2285 #-----------------------
2286 # 快速排序
2287 #
2288 def Function_Algorithm_QuickSort(alist, start, end):
2289     """快速排序"""
2290     local_var_alist = alist
2291     local_var_start = start
2292     local_var_end   = end
2293 
2294     # 递归的退出条件
2295     if local_var_start >= local_var_end:
2296         return
2297 
2298     # 设定起始元素为要寻找位置的基准元素
2299     list_mid = local_var_alist[local_var_start]
2300     # low为序列左边的由左向右移动的游标
2301     list_low = local_var_start
2302     # high为序列右边的由右向左移动的游标
2303     list_high = local_var_end
2304 
2305     print("1 >>",list_low,list_mid,list_high)
2306 
2307     while list_low < list_high:
2308         print("L H",list_low,list_high)
2309         # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
2310         while list_low < list_high and local_var_alist[list_high] >= list_mid:
2311             list_high -= 1
2312         # 将high指向的元素放到low的位置上
2313         local_var_alist[list_low] = local_var_alist[list_high]
2314         print("2 >>", local_var_alist[list_low] )
2315         # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
2316         while list_low < list_high and local_var_alist[list_low] < list_mid:
2317             list_low += 1
2318         # 将low指向的元素放到high的位置上
2319         local_var_alist[list_high] = local_var_alist[list_low]
2320         print("3 >>", local_var_alist[list_high])
2321         print("----------")
2322     # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
2323     # 将基准元素放到该位置
2324 
2325     local_var_alist[list_low] = list_mid
2326     print("4 >>", local_var_alist[list_low])
2327     print("==================")
2328     # # 对基准元素左边的子序列进行快速排序
2329     Function_Algorithm_QuickSort(local_var_alist, local_var_start, list_low-1)
2330     #
2331     # # 对基准元素右边的子序列进行快速排序
2332     Function_Algorithm_QuickSort(local_var_alist, list_low+1, local_var_end)
2333 
2334 #-----------------------
2335 # 希尔排序
2336 def Function_Algorithm_ShellSort(alist):
2337     n = len(alist)
2338     # 初始步长
2339     var = n / 2
2340     gap = int(var)
2341     print(gap,type(gap))
2342     while gap > 0:
2343         # 按步长进行插入排序
2344         for i in range(gap, n):
2345             j = i
2346             # 插入排序
2347             while j>=gap and alist[j-gap] > alist[j]:
2348                 alist[j-gap], alist[j] = alist[j], alist[j-gap]
2349                 j -= gap
2350         # 得到新的步长
2351         gap = gap / 2
2352 
2353 
2354 
2355 #-----------------------
2356 # 归并排序
2357 # def merge_sort(alist):
2358 #     if len(alist) <= 1:
2359 #         return alist
2360 #     # 二分分解
2361 #     num = len(alist)/2
2362 #     print(num)
2363 #     left = merge_sort(alist[:num])
2364 #     print(left)
2365 #     right = merge_sort(alist[num:])
2366 #     # 合并
2367 #     return merge(left,right)
2368 
2369 # def merge(left, right):
2370 #     '''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组'''
2371 #     #left与right的下标指针
2372 #     l, r = 0, 0
2373 #     result = []
2374 #     while l<len(left) and r<len(right):
2375 #         if left[l] < right[r]:
2376 #             result.append(left[l])
2377 #             l += 1
2378 #         else:
2379 #             result.append(right[r])
2380 #             r += 1
2381 #     result += left[l:]
2382 #     result += right[r:]
2383 #     return result
2384 
2385 
2386 #-----------------------
2387 #
2388 
2389 
2390 #----------------------------------------------
2391 # ============================================================================
2392 '''
2393 # ============================================================================
2394 #   测试专用
2395 # ============================================================================
2396 '''
2397 if __name__ == "__main__":
2398 
2399     # #-----------------------
2400     # # 引入
2401     # start_time = time.time()
2402     #
2403     # # 注意是三重循环
2404     # for a in range(0, 1001):
2405     #     for b in range(0, 1001):
2406     #         for c in range(0, 1001):
2407     #             if a ** 2 + b ** 2 == c ** 2 and a + b + c == 1000:
2408     #                 print("a, b, c: %d, %d, %d" % (a, b, c))
2409     #
2410     # end_time = time.time()
2411     # print("elapsed: %f" % (end_time - start_time))
2412     # print("complete!")
2413     # #
2414     
2415 
2416 
2417     #-----------------------
2418     # start_time = time.time()
2419     #
2420     # # 注意是两重循环
2421     # for a in range(0, 1001):
2422     #     for b in range(0, 1001 - a):
2423     #         c = 1000 - a - b
2424     #         if a ** 2 + b ** 2 == c ** 2:
2425     #             print("a, b, c: %d, %d, %d" % (a, b, c))
2426     #
2427     # end_time = time.time()
2428     # print("elapsed: %f" % (end_time - start_time))
2429     # print("complete!")
2430     # #
2431 
2432 
2433 
2434     # -----------------------
2435     # 1.7
2436     # # 固定格式
2437     # #创建对象:函数名 测试代码语句  运行代码设置
2438     # time_A = Timer("Function_Test_A()", "from __main__ import Function_Test_A")
2439     # # 执行速度设置 固定格式
2440     # print("time_A:", time_A.timeit(number=100), "seconds")
2441     #
2442     # time_B = Timer("Function_Test_B()", "from __main__ import Function_Test_B")
2443     # print("time_B ", time_B.timeit(number=100), "seconds")
2444     # time_C = Timer("Function_Test_C()", "from __main__ import Function_Test_C")
2445     # print("time_C ", time_C.timeit(number=100), "seconds")
2446     # time_D = Timer("Function_Test_D()", "from __main__ import Function_Test_D")
2447     # print("time_D ", time_D.timeit(number=100), "seconds")
2448     # #
2449 
2450 
2451 
2452     # # -----------------------
2453     # # 单链表
2454     # single_list_name_A = SingleLinkList()
2455     # single_list_name_A.add(11)       # 头部添加元素
2456     # single_list_name_A.add(12)       # 头部添加元素
2457     # single_list_name_A.add(13)       # 头部添加元素
2458     # single_list_name_A.append(24)    # 尾部添加元素
2459     # single_list_name_A.insert(3, 35) # 指定位置添加元素
2460     # single_list_name_A.append(26)    # 尾部添加元素
2461     # single_list_name_A.travel()      # 遍历链表
2462     # print ("Length:[%s]"%(single_list_name_A.length()))
2463     # print(single_list_name_A.search(35)) # 查找节点是否存在
2464     # print(single_list_name_A.search(15)) # 查找节点是否存在
2465     # single_list_name_A.remove(11)        # 删除节点
2466     # single_list_name_A.travel()          # 遍历链表
2467     # print("Length:[%s]" % (single_list_name_A.length()))
2468     # #
2469 
2470 
2471     # # -----------------------
2472     # # 单链表循环
2473     # single_list_name_B = Class_SinCyc_Linkedlist()
2474     # print("Length:[%s]" % (single_list_name_B.length()))
2475     # single_list_name_B.add(11)          # 头部添加元素
2476     # single_list_name_B.add(12)          # 头部添加元素
2477     # single_list_name_B.add(13)          # 头部添加元素
2478     # single_list_name_B.append(21)       # 尾部添加元素
2479     # single_list_name_B.insert(1, 31)    # 指定位置添加元素
2480     # single_list_name_B.insert(3, 32)    # 指定位置添加元素
2481     # single_list_name_B.insert(5, 33)    # 指定位置添加元素
2482     # single_list_name_B.append(22)       # 尾部添加元素
2483     # single_list_name_B.travel()         # 遍历链表
2484     # print("Length:[%s]" % (single_list_name_B.length()))
2485     # print(single_list_name_B.search(11))# 查找节点是否存在
2486     # print(single_list_name_B.search(22))# 查找节点是否存在
2487     # print(single_list_name_B.search(55))# 查找节点是否存在
2488     # single_list_name_B.remove(11)
2489     # single_list_name_B.travel()  # 遍历链表
2490     # print("Length:[%s]" % (single_list_name_B.length()))
2491     # #
2492 
2493 
2494     # # -----------------------
2495     # # 双向链表
2496     # single_list_name_C = Class_Double_LinkList()
2497     # print("Length:[%s]" % (single_list_name_C.length()))
2498     # single_list_name_C.add(111)         # 头部添加元素
2499     # single_list_name_C.add(112)         # 头部添加元素
2500     # single_list_name_C.add(113)         # 头部添加元素
2501     # single_list_name_C.add(114)         # 头部添加元素
2502     # single_list_name_C.add(115)         # 头部添加元素
2503     # single_list_name_C.append(211)      # 尾部添加元素
2504     # single_list_name_C.append(212)      # 尾部添加元素
2505     # single_list_name_C.append(213)      # 尾部添加元素
2506     # single_list_name_C.travel()         # 遍历链表
2507     # print("Length:[%s]" % (single_list_name_C.length()))
2508     # single_list_name_C.insert(2, 311)     # 指定位置添加元素
2509     # single_list_name_C.insert(4, 312)     # 指定位置添加元素
2510     # single_list_name_C.insert(6, 313)     # 指定位置添加元素
2511     # print(single_list_name_C.search(111)) # 查找节点是否存在
2512     # print(single_list_name_C.search(211)) # 查找节点是否存在
2513     # print(single_list_name_C.search(311)) # 查找节点是否存在
2514     # single_list_name_C.travel()           # 遍历链表
2515     # print("Length:[%s]" % (single_list_name_C.length()))
2516     # single_list_name_C.remove(112)
2517     # single_list_name_C.remove(113)
2518     # single_list_name_C.remove(114)
2519     # single_list_name_C.remove(115)
2520     # single_list_name_C.remove(211)
2521     # single_list_name_C.remove(212)
2522     # single_list_name_C.travel()  # 遍历链表
2523     # print("Length:[%s]" % (single_list_name_C.length()))
2524     # #
2525 
2526 
2527 
2528     # # # -----------------------
2529     # # 队列
2530     # queue_name_A = Class_Queue()        # 创建对象
2531     # queue_name_A.enqueue("hello")       # 进队列
2532     # queue_name_A.enqueue("world")       # 进队列
2533     # queue_name_A.enqueue("it cast")     # 进队列
2534     # print(queue_name_A.size())
2535     # queue_name_A.dequeue()              # 出队列
2536     # print(queue_name_A.size())
2537     # queue_name_A.dequeue()              # 出队列
2538     # print(queue_name_A.size())
2539     # queue_name_A.dequeue()              # 出队列
2540     # print(queue_name_A.size())
2541     # #
2542     
2543     
2544     # # -----------------------
2545     # # 双端队列
2546     # Class_Double_Queue = Class_Double_Queue()
2547     # Class_Double_Queue.add_front(111)           # 从队头加入一个item元素
2548     # Class_Double_Queue.add_front(112)           # 从队头加入一个item元素
2549     # Class_Double_Queue.add_rear(213)            # 从队尾加入一个item元素
2550     # Class_Double_Queue.add_rear(214)            # 从队尾加入一个item元素
2551     # Class_Double_Queue.size()
2552     # print(Class_Double_Queue.size())
2553     # Class_Double_Queue.remove_front()           # 从队头删除一个item元素
2554     # print(Class_Double_Queue.size())
2555     # Class_Double_Queue.remove_front()           # 从队头删除一个item元素
2556     # print(Class_Double_Queue.size())
2557     # Class_Double_Queue.remove_rear()            # 从队尾删除一个item元素
2558     # print(Class_Double_Queue.size())
2559     # Class_Double_Queue.remove_rear()            # 从队尾删除一个item元素
2560     # print(Class_Double_Queue.size())
2561     # #
2562 
2563 
2564 
2565     # #-----------------------
2566     # # 冒泡排序
2567     # BubbleSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20]
2568     # print("P",BubbleSort_name_A)    # 前
2569     # Function_Algorithm_BubbleSort(BubbleSort_name_A)
2570     # print("N",BubbleSort_name_A)    # 后
2571     # #
2572 
2573 
2574     # # #-----------------------
2575     # # 选择排序
2576     # SelectionSort_name_A = [54, 226, 93, 17, 77, 31, 44, 55, 20]
2577     # print("P",SelectionSort_name_A)
2578     # Function_Algorithm_SelectionSort(SelectionSort_name_A)
2579     # print("N",SelectionSort_name_A)
2580     # #
2581 
2582 
2583 
2584     # # #-----------------------
2585     # # 插入排序
2586     # InsertionSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20]
2587     # print("P",InsertionSort_name_A)
2588     # Function_Algorithm_InsertSort(InsertionSort_name_A)
2589     # print("N",InsertionSort_name_A)
2590     # #
2591 
2592 
2593     # # #-----------------------
2594     # # #快速排序
2595     # QuickSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20]
2596     # print("P", QuickSort_name_A)
2597     # Function_Algorithm_QuickSort(QuickSort_name_A, 0, len(QuickSort_name_A) - 1)
2598     # print("N", QuickSort_name_A)
2599     # #
2600 
2601 
2602 
2603     # #-----------------------
2604     # # 希尔排序
2605     # ShellSort_name_A = [54, 26, 93, 17, 77, 31, 44, 55, 20, 99]
2606     # print(ShellSort_name_A)
2607     # Function_Algorithm_ShellSort(ShellSort_name_A)
2608     # print(ShellSort_name_A)
2609     # #
2610 
2611 
2612     # #-----------------------
2613     # # 归并排序  不成立
2614     # alist = [54, 26, 93, 17, 77, 31, 44, 55, 20,78]
2615     # # sorted_alist = merge_sort(alist)
2616     # asd = merge_sort(alist)
2617     # print(asd)
2618     # # print(sorted_alist)
2619 
2620     print(" learn finish")

 

--------

--------------------------------------------

posted @ 2018-11-19 19:05  楚格  阅读(319)  评论(0编辑  收藏  举报