二叉树练习 2

本文探讨了二叉树的相关概念和操作,包括构造高度平衡的二叉树、计算节点数量、查找节点、收集叶子节点和内部节点、构建完整二叉树等。通过Prolog语言实现,涉及高度平衡树的最小和最大节点数计算,以及在列表中收集特定层级节点的方法。此外,还展示了如何将列表转换为堆,并进行查找操作,比较了列表和堆在查找效率上的差异。
摘要由CSDN通过智能技术生成

转载自:https://mp.weixin.qq.com/s/I2hjkWOV1e2qaQuE8ASwVg

7、使用给定数量的节点构造高度平衡的二叉树

考虑一个高度为H的高度平衡的二叉树。它可以包含的最大节点数是多少?显然,MaxN = 2 ** H-1。但是,最小数MinN是多少?这个问题比较困难。尝试找到一个递归语句并将其转换为谓词minNodes/2,定义为以下形式:

minNodes(H,N):- N是高度为H的高度平衡二叉树中的最小节点数。

另一方面,我们可能会问:具有N个节点的高度平衡的二叉树可以具有的最大高度H是多少?定义为以下形式:

maxHeight(N,H):-H是具有N个节点的高度平衡二叉树的最大高度

现在,我们可以解决主要问题:使用给定的节点数量构造所有高度平衡的二叉树。

hbal_tree_nodes(N,T):-T是具有N个节点的高度平衡的二叉树。

 

1  :- ensure_loaded(p4_06).

2  

3  minNodes(0,0) :- !.

4  minNodes(1,1) :- !.

5  minNodes(H,N) :- 

6 H > 1,

7 H1 is H - 1,

8 H2 is H - 2,

9 minNodes(H1,N1),

10 minNodes(H2,N2),

11 N is 1 + N1 + N2.

12

行注释:

1.  装入hbal_tree/2谓词

2.  空行

3.  高为0节点为0

4.  高为1时节点为1

5.  N是高度为H的高度平衡二叉树中的最小节点数

6.  确保树的高度大于1

7.  下一层树

8.  自己思考一下试试,然后想办法验证一下

9.  左树

10. 右树

11. 建议手工推演一下

12. 空行

 

13 maxNodes(H,N) :- 

14 N is 2**H - 1.

15

16 minHeight(0,0) :- !.

17 minHeight(N,H) :- 

18 N > 0,

19 N1 is N//2,

20 minHeight(N1,H1),

21 H is H1 + 1.

22

行注释:

13. N是高度为H的高度平衡二叉树中的最大节点数

14. 最大节点数是2的H次幂减1

15. 

16. H是具有N个节点的高平衡二叉树的最小高度

17. 

18. 确保N大于0

19. 将树分两半

20. 取矮的计算

21. 那么正常高度就为结果值增加1

22. 

 

23 maxHeight(N,H) :- 

24 maxHeight(N,H,1,1).

25

26 maxHeight(N,H,H1,N1) :- 

27  N1 > N, !,

28 H is H1 - 1. 

29 maxHeight(N,H,H1,N1) :- 

30 N1 =< N

31 H2 is H1 + 1, 

32 minNodes(H2,N2),

33 maxHeight(N,H,H2,N2).

34

行注释:

23. H是具有N个节点的高度平衡的二叉树的最大高

24. 调用maxHeight/4

25. 

26. 

27. 当N小于N1时截断

28. 

29. 

30. 

31. 

32. 给定高的最少节点,获得最小节点数

33. 由减点数得到高

34. 

 

 

35 hbal_tree_nodes(N,T) :- 

36 minHeight(N,Hmin), 

37 maxHeight(N,Hmax),

38 between(Hmin,Hmax,H),

39 hbal_tree(H,T),

40 nodes(T,N).

41

行注释:

35. T是具有N个节点的高平衡的二叉树

36. 由节点数得到最小高

37. 由节点数得到最大高

38. H取值从Hmin起到Hmax值区间内的数

39. 由H得到高平衡的数

40. 过滤掉节点数不是N的数

41. 空行

 

42 nodes(nil,0).

43 nodes(t(_,Left,Right),N) :-

44 nodes(Left,NLeft),

45 nodes(Right,NRight),

46 N is NLeft + NRight + 1.

47

48 count_hbal_trees(N,C) :- 

49 setof(T,hbal_tree_nodes(N,T),Ts),

50 length(Ts,C).

行注释:

42. 二叉树T有N个节点

43. 

44. 递归验证左树

45. 递归验证右树

46. 左树节点数+右树节点数+根节点1

47. 空行

48. 有N个节点的C个不同的高度平衡二叉树

49. 根据参数1中的指示T,将参数2中T的所有解放到参数3的列表中

50. 获取列表Ts的长度C

测试:

?- consult('p4_07.pl').

true.

 

?- hbal_tree_nodes(7,T).

T = t(x, t(x, t(x, nil, nil), t(x, nil, nil)), t(x, t(x, nil, nil), t(x, nil, nil))) .

 

?- count_hbal_trees(4,C).

[t(x,t(x,nil,nil),t(x,nil,t(x,nil,nil))),t(x,t(x,nil,nil),t(x,t(x,nil,nil),nil)),t(x,t(x,nil,t(x,nil,nil)),t(x,nil,nil)),t(x,t(x,t(x,nil,nil),nil),t(x,nil,nil))]

C = 4.

 

?- 

 

8、计算二叉树的叶子

叶子是没有后继的节点。谓词count_leaves/2对页节点进行计数。

count_leaves(T,N) :- 二叉树T有N个叶节点

 

1  count_leaves(nil,0).

2  count_leaves(t(_,nil,nil),1).

3  count_leaves(t(_,L,nil),N) :- 

4 L = t(_,_,_),

5 count_leaves(L,N).

6  count_leaves(t(_,nil,R),N) :- 

7 R = t<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值