不规则递归转换为while,留底
我发现当参数并不太多时,从性能的角度来看,没必要用一个class来保存参数(虽然看起来更加生动形象),直接用最简单的元组就可以了.
from hanoi import *
# example trees for test...
trees=[]
trees.append(None)
trees.append([1,None,None])
trees.append([1,None,[2,None,None]])
trees.append([1,[3,[4,None,None],None],[600,None,None]])
trees.append([1,[3,[4,None,None],[6,None,None]],[2,[5,None,None],[7,None,None]]])
trees.append([10,[6,[8,None,None],[12,None,None]],[11,None,[15,None,None]]])
trees.append([10,[6,[8,[11,None,[15,None,None]],None],[12,None,None]],[10,[6,[8,None,None],[12,None,None]],[11,None,[15,None,None]]]]) # helper functions to build a valid preorder or inorder list from a tree
def _pre(tree):
if tree:
yield tree[0]
yield from _pre(tree[1])
yield from _pre(tree[2])
def _ino(tree):
if tree:
yield from _ino(tree[1])
yield tree[0]
yield from _ino(tree[2])
def pre(tree):
return list(_pre(tree))
def ino(tree):
return list(_ino(tree)) def make(prd,ind):
if prd and ind:
root = prd[0]
root_pos = ind.index(root)
ind_left= ind[:root_pos]
ind_right = ind[root_pos+1:]
cut = len(ind_left)+1
prd_left = prd[1:cut]
prd_right = prd[cut:]
left = make(prd_left,ind_left)
right = make(prd_right,ind_right)
return [root,left,right] def xmake(prd,ind):
stacks=[Stack(stg=0,prd=prd,ind=ind)]
while stacks:
c = stacks.pop()
if c.stg==0:
c.stg=1
if c.prd and c.ind:
root=c.prd[0]
c.tree_list=[root]
root_pos = c.ind.index(root)
ind_left = c.ind[:root_pos]
cut = len(ind_left)+1
prd_left = c.prd[1:cut]
c.ind_right = c.ind[root_pos+1:]
c.prd_right = c.prd[cut:]
stacks.append(c)
stacks.append(Stack(stg=0,prd=prd_left,ind=ind_left))
else:
res = None
elif c.stg==1:
c.stg=2
c.tree_list.append(res)
stacks.append(c)
stacks.append(Stack(stg=0,prd=c.prd_right,ind=c.ind_right))
elif c.stg==2:
c.tree_list.append(res)
res=c.tree_list
return res def ymake(prd,ind):
stacks=[(0,prd,ind,None,None,None,)]
while stacks:
stg,prd,ind,tree_list,prd_right,ind_right = stacks.pop()
if stg==0:
if prd and ind:
root=prd[0]
tree_list=[root]
root_pos = ind.index(root)
ind_left = ind[:root_pos]
cut = len(ind_left)+1
prd_left = prd[1:cut]
ind_right = ind[root_pos+1:]
prd_right = prd[cut:]
stacks.append((1,None,None,tree_list,prd_right,ind_right,))
stacks.append((0,prd_left,ind_left,None,None,None,))
else:
res = None
elif stg==1:
tree_list.append(res)
stacks.append((2,None,None,tree_list,None,None,))
stacks.append((0,prd_right,ind_right,None,None,None,))
elif stg==2:
tree_list.append(res)
res=tree_list
return res if __name__=='__main__':
for tree in trees:
preorder = pre(tree)
inorder = ino(tree)
compare(1,10000,make,xmake,ymake,prd=preorder,ind=inorder)
时间消耗情况"
>>>
1 groups, 10000 times
make best time: 0.005802598746597618
xmake best time: 0.040378714824230735
ymake best time: 0.010430907850763435
1 groups, 10000 times
make best time: 0.023853132543773928
xmake best time: 0.15266406806261454
ymake best time: 0.06813018108264718
1 groups, 10000 times
make best time: 0.061869156080883114
xmake best time: 0.29423481944120744
ymake best time: 0.14889103182256502
1 groups, 10000 times
make best time: 0.09127643060422885
xmake best time: 0.4971307733591055
ymake best time: 0.22370901906617036
1 groups, 10000 times
make best time: 0.15408382101704765
xmake best time: 0.8039180049905172
ymake best time: 0.37127052922146664
1 groups, 10000 times
make best time: 0.1331591427600083
xmake best time: 0.6996409992152874
ymake best time: 0.32450677483017465
1 groups, 10000 times
make best time: 0.2689833157646033
xmake best time: 1.3633301759510097
ymake best time: 0.6343635807709003
不规则递归转换为while,留底的更多相关文章
- 记住经典的斐波拉契递归和阶乘递归转换为while规律
记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路. # 斐波拉契--树形递归 def fab(n): if n<3: return n return fa ...
- 一个貌似比较吊的递归转换为loop--总算成功了.--第二弹
前段时间用类似于散弹式编程的方式,各种猜测-运行验证-修正结果,最终成功转换了一个看起来比较有难度的递归函数.但总觉得很蛋疼,原因如下: 1.虽然正确,但是逻辑搞得比较复杂.现在去看,一头雾水,不知道 ...
- 将树形递归转换为loop
class Stack(object): def __init__(self,**kwargs): self.__dict__.update(kwargs) def __str__(self): re ...
- 一个貌似比较吊的递归转换为loop--总算成功了.
class Stack(object): """ A class to hold arguements and state data. """ ...
- 数据结构笔记01:编程面试过程中常见的10大算法(java)
以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...
- JavaScript 开发总结(一)
数据类型:JavaScript定义的数据类型有字符串.数字.布尔.数组.对象.Null.Undefined,但typeof有区分可判别的数据分类是number.string.boolean.objec ...
- python 排序算法
冒泡排序: 一. 冒泡排序的定义 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是重复地进 ...
- Java 算法 概念汇总
编程面试的10大算法概念汇总 以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java ...
- 面试10大算法汇总——Java篇
问题导读 1 字符串和数组 2 链表 3 树 4 图 5 排序 6 递归 vs 迭代 7 动态规划 8 位操作 9 概率问题 10 排列组合 11 其他 -- 寻找规律 英文版 以下从Java角度解释 ...
随机推荐
- 高并发下,log4j日志打印行数导致的内存溢出问题
log4j日志打印时,如果将行数打印出来,在调用量极大的情况下,会出现内存溢出问题. log4j打印日志,打印行数时,行数是通过一个一个exception抛出,再极高调用量的情况下,内存会因为exce ...
- ES6 new syntax of Rest and Spread Operators
Rest and Spread Operators.md Why we need rest and spread operators? var showCollections = function(i ...
- 【转】C++ Vector(向量容器)
转自:https://blog.csdn.net/studentyyl/article/details/21177445 vector是一个线性顺序结构.相当于数组,但其大小可以不预先指定,并且自动扩 ...
- 在脚本中使用source命令不生效
问题描述 1. 一次写自动化安装脚本,要安装java,需要将JAVA_HOME写到/etc/profile中,然后使用source命令,但是发现profile文件中确实有JAVA_HOME,使用 ...
- [HEOI 2014]大工程
Description 题库链接 给你一个 \(n\) 个节点的树, \(q\) 组询问,每次给出 \(k\) 个关键点,询问这 \(k\) 个关键点两两间路径长度和,长度最值. \(1\leq n\ ...
- [HNOI2011]赛车游戏
题目描述 名歌手LAALA最近迷上了一款赛车游戏,游戏中开车的玩家在不同的路段需要选择不同的速度,使得自己在最短的时间内到达终点.开始游戏时,车内的初始油量为f,所以游戏的关键是如何在速度和耗油量之间 ...
- APIO dispatching
题目描述 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增 ...
- 51 nod 1456 小K的技术(强连通 + 并查集)
1456 小K的技术 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 苏塞克王国是世界上创新技术的领先国家,在王国中有n个城市 ...
- poj2828 BuyTickets 线段树
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 17326 Accepted: 8601 Desc ...
- HDU 5506(GT and set)
题意: 表示看了很久,然而发现还是没看懂题. 正解:给你a个集合,让你把他们合并成k个,当两个集合有公共数字时可以合并. (一直以为是合并后,每个集合至少有两个数字相同- -,这英语也是醉了) 思路: ...