Java实现二叉树的遍历.docx
- 文档编号:9129294
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:84
- 大小:88.47KB
Java实现二叉树的遍历.docx
《Java实现二叉树的遍历.docx》由会员分享,可在线阅读,更多相关《Java实现二叉树的遍历.docx(84页珍藏版)》请在冰豆网上搜索。
Java实现二叉树的遍历
一、数据结构分类
(一)按逻辑结构
1.集合(无辑关系)
2.线性结构(线性表):
数组、链表、栈、队列
3.非线性结构:
树、图、多维数组
(二)按存储结构
顺序(数组)储结构、链式储结构、索引储结构、散列储结构
二、二叉树相关性质
∙结点的度:
一个结点的子树的个数记为该结点的度.
∙树的度:
所有节点中度数最大的结节的度数,叶子节点的度为零。
∙树的高度:
一棵树的最大层次数记为树的高度(或深度)。
∙有序(无序)树:
若将树中结点的各子树看成是从左到右具有次序的,即不能交换,则称该树为有序树。
否则称为无序树。
∙二叉树第i层(i≥1)上至多有2^(i-1)个节点。
∙深度为k的二叉树至多有2^k-1个节点(k≥1)。
∙对任何一棵二叉,若叶子节点数为n0,度为2的节点数为n2,则n0=n2+1。
∙具有n个节点的完全二叉树的深度为(㏒2^n)(向下取整)+1。
∙对一棵有n个节点的完全二叉树的节点按层次从上到下,自左至右进行编号,则对任一节点i(1≤i≤n)有:
若i=1,则节点i是二叉树的根,无双亲;若i>1,则其双亲为i/2(向下取整)。
若2i>n,则节点i没有孩子节点,否则其左孩子为2i。
若2i+1>n,则节点i没有右孩子,否则其右孩子为2i+1。
∙若深度为k的二叉树有2^k-1个节点,则称其为满二叉树。
满二叉树是一棵完全二叉树。
∙对于完全二叉树中,度为1的节点个数只可能为1个或0个。
∙对于二叉树,如果叶子节点数为n0,度为1的节点数为n1,度为2的节点数为n2,则节点总数n=n0+n1+n2。
∙对于任意树,总节点数=每个节点度数和+1
∙二叉树的高度等于根与最远叶节点(具有最多祖先的节点)之间分支数目。
空树的高度是-1。
只有单个元素的二叉树,其高度为0。
.
三、二叉树的遍历
遍历是按某种策略访问树中的每个节点,且仅访问一次。
(一)二叉树结构实现
Java代码
1.package tree.bintree;
2./**
3. * 创建 非完全二叉树、完全二叉树、满二叉树
4. *
5. * 由于二叉树的节点增加没有什么规则,所以这里只是简单的使用了递一
6. * 次性把整棵树创建出来,而没有设计出一个一个添加节点的方法与删除
7. *
8. * @author jzj
9. * @date 2009-12-23
10. */
11.public class BinTree {// Bin=Binary(二进位的, 二元的)
12.
13. protected Entry root;//根
14. private int size;//树的节点数
15.
16. /**
17. * 树的节点结构
18. * @author jzj
19. * @date 2009-12-23
20. */
21. protected static class Entry {
22. int elem;//数据域,这里我们作为编号
23. Entry left;//左子树
24. Entry right;//右子树
25.
26. public Entry(int elem) {
27. this.elem = elem;
28. }
29.
30. public String toString() {
31. return " number=" + elem;
32. }
33. }
34.
35. /**
36. * 根据给定的节点数创建一个完全二叉树或是满二叉树
37. * @param nodeCount 要创建节点总数
38. */
39. public void createFullBiTree(int nodeCount) {
40. root = recurCreateFullBiTree(1, nodeCount);
41. }
42.
43. /**
44. * 递归创建完全二叉树
45. * @param num 节点编号
46. * @param nodeCount 节点总数
47. * @return TreeNode 返回创建的节点
48. */
49. private Entry recurCreateFullBiTree(int num, int nodeCount) {
50. size++;
51. Entry rootNode = new Entry(num);//根节点
52. //如果有左子树则创建左子树
53. if (num * 2 <= nodeCount) {
54. rootNode.left = recurCreateFullBiTree(num * 2, nodeCount);
55. //如果还可以创建右子树,则创建
56. if (num * 2 + 1 <= nodeCount) {
57. rootNode.right = recurCreateFullBiTree(num * 2 + 1, nodeCount);
58. }
59. }
60. return (Entry) rootNode;
61. }
62.
63. /**
64. * 根据给定的数组创建一棵树,这个棵树可以是完全二叉树也可是普通二叉树
65. * 数组中为0的表示不创建该位置上的节点
66. * @param nums 数组中指定了要创建的节点的编号,如果为0,表示不创建
67. */
68. public void createBinTree(int[] nums) {
69. root = recurCreateBinTree(nums, 0);
70. }
71.
72. /**
73. * 递归创建二叉树
74. * @param nums 数组中指定了要创建的节点的编号,如果为0,表示不创建
75. * @param index 需要使用数组中的哪个元素创建节点,如果为元素为0,则不创建
76. * @return TreeNode 返回创建的节点,最终会返回树的根节点
77. */
78. private Entry recurCreateBinTree(int[] nums, int index) {
79. //指定索引上的编号不为零上才需创建节点
80. if (nums[index] !
= 0) {
81. size++;
82. Entry rootNode = new Entry(nums[index]);//根节点
83. //如果有左子树则创建左子树
84. if ((index + 1) * 2 <= nums.length) {
85. rootNode.left = (Entry) recurCreateBinTree(nums, (index + 1) * 2 - 1);
86. //如果还可以创建右子树,则创建
87. if ((index + 1) * 2 + 1 <= nums.length) {
88. rootNode.right = (Entry) recurCreateBinTree(nums, (index + 1) * 2);
89. }
90. }
91. return (Entry) rootNode;
92. }
93. return null;
94.
95. }
96.
97. public int size() {
98. return size;
99. }
100.
101. //取树的最左边的节点
102. public int getLast() {
103. Entry e = root;
104. while (e.right !
= null) {
105. e = e.right;
106. }
107. return e.elem;
108. }
109.
110. //测试
111. public static void main(String[] args) {
112.
113. //创建一个满二叉树
114. BinTree binTree = new BinTree();
115. binTree.createFullBiTree(15);
116. System.out.println(binTree.size());//15
117. System.out.println(binTree.getLast());//15
118.
119. //创建一个完全二叉树
120. binTree = new BinTree();
121. binTree.createFullBiTree(14);
122. System.out.println(binTree.size());//14
123. System.out.println(binTree.getLast());//7
124.
125. //创建一棵非完全二叉树
126. binTree = new BinTree();
127. int[] nums = new int[] { 1, 2, 3, 4, 0, 0, 5, 0, 6, 0, 0, 0, 0, 7, 8 };
128. binTree.createBinTree(nums);
129. System.out.println(binTree.size());//8
130. System.out.println(binTree.getLast());//8
131.
132. }
133.}
packagetree.bintree;
/**
*创建非完全二叉树、完全二叉树、满二叉树
*
*由于二叉树的节点增加没有什么规则,所以这里只是简单的使用了递一
*次性把整棵树创建出来,而没有设计出一个一个添加节点的方法与删除
*
*@authorjzj
*@date2009-12-23
*/
publicclassBinTree{//Bin=Binary(二进位的,二元的)
protectedEntryroot;//根
privateintsize;//树的节点数
/**
*树的节点结构
*@authorjzj
*@date2009-12-23
*/
protectedstaticclassEntry{
intelem;//数据域,这里我们作为编号
Entryleft;//左子树
Entryright;//右子树
publicEntry(intelem){
this.elem=elem;
}
publicStringtoString(){
return"number="+elem;
}
}
/**
*根据给定的节点数创建一个完全二叉树或是满二叉树
*@paramnodeCount要创建节点总数
*/
publicvoidcreateFullBiTree(intnodeCount){
root=recurCreateFullBiTree(1,nodeCount);
}
/**
*递归创建完全二叉树
*@paramnum节点编号
*@paramnodeCount节点总数
*@returnTreeNode返回创建的节点
*/
privateEntryrecurCreateFullBiTree(intnum,intnodeCount){
size++;
EntryrootNode=newEntry(num);//根节点
//如果有左子树则创建左子树
if(num*2<=nodeCount){
rootNode.left=recurCreateFullBiTree(num*2,nodeCount);
//如果还可以创建右子树,则创建
if(num*2+1<=nodeCount){
rootNode.right=recurCreateFullBiTree(num*2+1,nodeCount);
}
}
return(Entry)rootNode;
}
/**
*根据给定的数组创建一棵树,这个棵树可以是完全二叉树也可是普通二叉树
*数组中为0的表示不创建该位置上的节点
*@paramnums数组中指定了要创建的节点的编号,如果为0,表示不创建
*/
publicvoidcreateBinTree(int[]nums){
root=recurCreateBinTree(nums,0);
}
/**
*递归创建二叉树
*@paramnums数组中指定了要创建的节点的编号,如果为0,表示不创建
*@paramindex需要使用数组中的哪个元素创建节点,如果为元素为0,则不创建
*@returnTreeNode返回创建的节点,最终会返回树的根节点
*/
privateEntryrecurCreateBinTree(int[]nums,intindex){
//指定索引上的编号不为零上才需创建节点
if(nums[index]!
=0){
size++;
EntryrootNode=newEntry(nums[index]);//根节点
//如果有左子树则创建左子树
if((index+1)*2<=nums.length){
rootNode.left=(Entry)recurCreateBinTree(nums,(index+1)*2-1);
//如果还可以创建右子树,则创建
if((index+1)*2+1<=nums.length){
rootNode.right=(Entry)recurCreateBinTree(nums,(index+1)*2);
}
}
return(Entry)rootNode;
}
returnnull;
}
publicintsize(){
returnsize;
}
//取树的最左边的节点
publicintgetLast(){
Entrye=root;
while(e.right!
=null){
e=e.right;
}
returne.elem;
}
//测试
publicstaticvoidmain(String[]args){
//创建一个满二叉树
BinTreebinTree=newBinTree();
binTree.createFullBiTree(15);
System.out.println(binTree.size());//15
System.out.println(binTree.getLast());//15
//创建一个完全二叉树
binTree=newBinTree();
binTree.createFullBiTree(14);
System.out.println(binTree.size());//14
System.out.println(binTree.getLast());//7
//创建一棵非完全二叉树
binTree=newBinTree();
int[]nums=newint[]{1,2,3,4,0,0,5,0,6,0,0,0,0,7,8};
binTree.createBinTree(nums);
System.out.println(binTree.size());//8
System.out.println(binTree.getLast());//8
}
}
(二)利用二叉树本身特点进行递归遍历(属内部遍历)
由于二叉树所具有的递归性质,一棵非空的二叉树可以看作是由根节点、左子树和右子树3部分构成,因为若能依次遍历这3部分的信息,也就遍历了整个二叉树。
按照左子树的遍历在右子树的遍历之前进行的约定,根据访问根节点位置的不同,可以得到二叉的前序、中序、后序3种遍历方法。
Java代码
1.package tree.bintree;
2.
3./**
4. * 二叉树的三种 内部 遍历:
前序、中序、后序
5. * 但不管是哪种方式,左子树的遍历在右子树的遍历之前遍历是这有三种遍历方式都
6. * 必须遵循的约定
7. * @author jzj
8. * @date 2009-12-23
9. */
10.public class BinTreeInOrder extends BinTree {
11.
12. /**
13. * 节点访问者,可根据需要重写visit方法
14. */
15. static abstract class Visitor {
16. void visit(Object ele) {
17. System.out.print(ele + " ");
18. }
19. }
20.
21. public void preOrder(Visitor v) {
22. preOrder(v, root);
23. }
24.
25. /**
26. * 树的前序递归遍历 pre=prefix(前缀)
27. * @param node 要遍历的节点
28. */
29. private void preOrder(Visitor v, Entry node) {
30. //如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null
31. if (node !
= null) {
32. v.visit(node.elem);//先遍历父节点
33. preOrder(v, node.left);//再遍历左节点
34. preOrder(v, node.right);//最后遍历右节点
35. }
36. }
37.
38. public void inOrder(Visitor v) {
39. inOrder(v, root);
40. }
41.
42. /**
43. * 树的中序递归遍历 in=infix(中缀)
44. * @param node 要遍历的节点
45. */
46. private void inOrder(Visitor v, Entry node) {
47. //如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null
48. if (node !
= null) {
49. inOrder(v, node.left);//先遍历左节点
50. v.visit(node.elem);//再遍历父节点
51. inOrder(v, node.right);//最后遍历右节点
52. }
53. }
54.
55. pu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 实现 二叉 遍历