不规则递归转换为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角度解释 ...
随机推荐
- 文件上传详解 (HTML FILE)
FileUpload 对象 在 HTML 文档中 <input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建. 该元素包含一个文 ...
- [LeetCode] Solve the Equation 解方程
Solve a given equation and return the value of x in the form of string "x=#value". The equ ...
- 1086: [SCOI2005]王室联邦
1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1554 Solved: ...
- BZOJ 1510: Kra-The Disks
Johnny 在生日时收到了一件特殊的礼物,这件礼物由一个奇形怪状的管子和一些盘子组成. 这个管子是由许多不同直径的圆筒(直径也可以相同) 同轴连接而成. 这个管子的底部是封闭的,顶部是打开的. 下图 ...
- [POJ1741]树上的点对 树分治
Description 给一棵有n个节点的树,每条边都有一个长度(小于1001的正整数). 定义dist(u,v)=节点u到节点v的最短路距离. 给出一个整数k,我们称顶点对(u,v)是合法的当且仅当 ...
- ●BZOJ 1096 [ZJOI2007]仓库建设
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1096 题解: 斜率优化DP $(d_i:i 位置到1位置的距离,p_i:i位置的成品数量,c ...
- 【NOIP2004】虫食算
Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +. 8468#6633 444455 ...
- ●BZOJ 4821 [Sdoi2017]相关分析
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4821 题解: 线段树是真的恶心,(也许是我的方法麻烦了一些吧)首先那个式子可以做如下化简: ...
- hdu 3436 splay树+离散化*
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- zoj2112 树状数组+主席树 区间动第k大
Dynamic Rankings Time Limit: 10000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Subm ...