不规则递归转换为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角度解释 ...
随机推荐
- JavaScript 递归
递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.通常涉及 函数调用自身. 能够像下面这样直接调用自身的方法或函数,是递归函数: var recursiveFunction = ...
- [LeetCode] Min Cost Climbing Stairs 爬楼梯的最小损失
On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay ...
- Discuz利用UC_KEY进行前台getshell
来源:http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0137991.html 先通过uc_key把恶意代码保存在/uc_client/data/ca ...
- PostgreSQL的insert注入
写这篇文是在昨夜的ctf中遇到的. ctf地址:bloody-feedback.quals.2017.volgactf.ru email存在注入,在ctf中发现注入就很好办了,只要找到能绕过的方法就行 ...
- 坑:JavaScript 中 操作符“==” 和“===” 的区别
标题:JavaScript 中 操作符"==" 和"===" 的区别 记录一些很坑的区别: 1. '' == '0' // false 0 == '' // t ...
- [POJ 3728]The merchant
Description There are N cities in a country, and there is one and only one simple path between each ...
- hdu 5266 pog loves szh III(lca + 线段树)
I - pog loves szh III Time Limit:6000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I ...
- mysql服务无法正常启动
这个时候多半是ini文件出了问题. 1.去检查你的my.ini的保存编码格式是不是ANSI,如果不是将其改为ANSI (一般我们修改my.ini时,都无法直接保存,而是选择另存为在其他目录下,再去替换 ...
- Python中高阶函数讲解
高阶函数讲解 1. 常规高阶函数 递归函数 格式:def func_name(variable): '''__doc__'''#函数的说明文档 if 条件表达式:#限制递归退出值 pass retur ...
- 使用EasyNetQ组件操作RabbitMQ消息队列服务
RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现,是实现消息队列应用的一个中间件,消息队列中间件是分布式系统中重要的组件,主要解决应用耦合, ...