二叉树

Posted hyunbar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树相关的知识,希望对你有一定的参考价值。

一、为什么需要树这种数据结构   

  1、数组存储方式的分析
  优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。
  缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低 [示意图]
  2、链式存储方式的分析
  优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可, 删除效率也很好)。
  缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历)
  3、树存储方式的分析
  能提高数据存储,读取的效率,  比如利用 二叉排序树(Binary Sort Tree),既可以保证数据的检索速度,同时也可以保证数据的插入,删除,修改的速度

二、二叉树的常用术语

 

  1. 节点
  2. 根节点
  3. 父节点
  4. 子节点
  5. 叶子节点 (没有子节点的节点)
  6. 节点的权(节点值)
  7. 路径(从root节点找到该节点的路线)
  8. 子树
  9. 树的高度(最大层数)
  10. 森林 :多颗子树构成森林

 

三、二叉树的概念  

  1. 树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树。
  2. 二叉树的子节点分为左节点和右节点
  3. 如果该二叉树的所有叶子节点都在最后一层,并且结点总数= 2^n -1 , n 为层数,则我们称为满二叉树。
  4. 如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为完全二叉树。

 

    技术图片

 

   技术图片

 

   技术图片

 

   

 

四、遍历 

  1、前序遍历

 

 1 //编写前序遍历的方法
 2 public void preOrder() 
 3     System.out.println(this); //先输出父结点
 4     //递归向左子树前序遍历
 5     if(this.left != null) 
 6         this.left.preOrder();
 7     
 8     //递归向右子树前序遍历
 9     if(this.right != null) 
10         this.right.preOrder();
11     
12 

 

 

  2、中序遍历

 

 1 //中序遍历
 2 public void infixOrder() 
 3     
 4     //递归向左子树中序遍历
 5     if(this.left != null) 
 6         this.left.infixOrder();
 7     
 8     //输出父结点
 9     System.out.println(this);
10     //递归向右子树中序遍历
11     if(this.right != null) 
12         this.right.infixOrder();
13     
14 

 

 

 

  3、后序遍历

 

 1 //后序遍历
 2 public void postOrder() 
 3     if(this.left != null) 
 4         this.left.postOrder();
 5     
 6     if(this.right != null) 
 7         this.right.postOrder();
 8     
 9     System.out.println(this);
10 

 

 

五、完整代码 

  

  1 package com.atguigu.tree;
  2 
  3 import org.junit.Test;
  4 
  5 /**
  6  * @author z
  7  * @createdate 2019-08-15 11:14
  8  */
  9 public class BinaryTreeTest 
 10     @Test
 11     public void test() 
 12         BinaryTree b = new BinaryTree();
 13         HeroNode root = new HeroNode(1, "宋江");
 14         HeroNode n1 = new HeroNode(2, "吴用");
 15         HeroNode n2 = new HeroNode(3, "玉麒麟");
 16         HeroNode n3 = new HeroNode(4, "关胜");
 17 
 18         b.setRoot(root);
 19         root.setLeft(n1);
 20         root.setRight(n2);
 21         n1.setLeft(n3);
 22         b.proOrder();
 23 
 24         b.findproOrder(5);
 25     
 26 
 27 
 28 class BinaryTree 
 29     public void setRoot(HeroNode root) 
 30         this.root = root;
 31     
 32 
 33     private HeroNode root;
 34 
 35     //前序遍历
 36     public void proOrder() 
 37         if (this.root != null) 
 38             this.root.proOrder();
 39          else 
 40             System.out.println("二叉树为空");
 41         
 42     
 43 
 44     //中序遍历
 45     public void infixOrder() 
 46         if (this.root != null) 
 47             this.root.infixOrder();
 48          else 
 49             System.out.println("二叉树为空");
 50         
 51     
 52 
 53     //后序遍历
 54     public void postOrder() 
 55         if (this.root != null) 
 56             this.root.postOrder();
 57          else 
 58             System.out.println("二叉树为空");
 59         
 60     
 61 
 62     //前序查找
 63     public void findproOrder(int no) 
 64         if (this.root != null) 
 65             HeroNode heroNode = this.root.findproOrder(no);
 66             if (heroNode != null)
 67                 System.out.println(heroNode);
 68             else
 69                 System.out.println("未知的英雄编号:" + no);
 70          else 
 71             System.out.println("二叉树为空");
 72         
 73     
 74 
 75     //中序查找
 76     public void findinfixOrder(int no) 
 77         if (this.root != null) 
 78             HeroNode heroNode = this.root.findinfixOrder(no);
 79             if (heroNode != null)
 80                 System.out.println(heroNode);
 81             else
 82                 System.out.println("未知的英雄编号:" + no);
 83          else 
 84             System.out.println("二叉树为空");
 85         
 86     
 87 
 88     //后序查找
 89     public void findpostOrder(int no) 
 90         if (this.root != null) 
 91             HeroNode heroNode = this.root.findpostOrder(no);
 92             if (heroNode != null)
 93                 System.out.println(heroNode);
 94             else
 95                 System.out.println("未知的英雄编号:" + no);
 96          else 
 97             System.out.println("二叉树为空");
 98         
 99     
100 
101 
102 class HeroNode 
103     private int no;
104     private String name;
105     private HeroNode left; //默认null
106     private HeroNode right; //默认null
107 
108     @Override
109     public String toString() 
110         return "HeroNode" +
111                 "no=" + no +
112                 ", name=‘" + name + \\‘ +
113                 /*", left=" + left +
114                 ", right=" + right +*/
115                 ;
116     
117 
118     public HeroNode(int no, String name) 
119         this.no = no;
120         this.name = name;
121     
122 
123     public int getNo() 
124         return no;
125     
126 
127     public void setNo(int no) 
128         this.no = no;
129     
130 
131     public String getName() 
132         return name;
133     
134 
135     public void setName(String name) 
136         this.name = name;
137     
138 
139     public HeroNode getLeft() 
140         return left;
141     
142 
143     public void setLeft(HeroNode left) 
144         this.left = left;
145     
146 
147     public HeroNode getRight() 
148         return right;
149     
150 
151     public void setRight(HeroNode right) 
152         this.right = right;
153     
154 
155     //编写前序遍历的方法
156     public void proOrder() 
157         System.out.println(this);
158         if (this.left != null) 
159             this.left.proOrder();
160         
161         if (this.right != null) 
162             this.right.proOrder();
163         
164     
165 
166     //编写中序遍历的方法
167     public void infixOrder() 
168         if (this.left != null) 
169             this.left.infixOrder();
170         
171         System.out.println(this);
172         if (this.right != null) 
173             this.right.infixOrder();
174         
175     
176 
177     //编写后序遍历的方法
178     public void postOrder() 
179         if (this.left != null) 
180             this.left.postOrder();
181         
182         if (this.right != null) 
183             this.right.postOrder();
184         
185         System.out.println(this);
186     
187 
188     //编写前序查找的方法
189     public HeroNode findproOrder(int no) 
190         if (this.no == no) 
191             return this;
192         
193         //1.则判断当前结点的左子节点是否为空,如果不为空,则递归前序查找
194         //2.如果左递归前序查找,找到结点,则返回
195         HeroNode h = null;
196         if (this.left != null) 
197             h = this.left.findproOrder(no);
198         
199         if (h != null) 
200             return h;
201         
202         //1.左递归前序查找,找到结点,则返回,否继续判断,
203         //2.当前的结点的右子节点是否为空,如果不空,则继续向右递归前序查找
204         if (this.right != null) 
205             h = this.right.findproOrder(no);
206         
207         return h;
208     
209 
210     //编写中序查找的方法
211     public HeroNode findinfixOrder(int no) 
212         HeroNode h = null;
213         if (this.left != null) 
214             h = this.left.findinfixOrder(no);
215         
216         if (h != null) 
217             return h;
218         
219         if (this.no == no) 
220             return this;
221         
222         if (this.right != null) 
223             h = this.right.findinfixOrder(no);
224         
225         return h;
226     
227 
228     //编写后序查找的方法
229     public HeroNode findpostOrder(int no) 
230         HeroNode h = null;
231         if (this.left != null) 
232             h = this.left.findpostOrder(no);
233         
234         if (h != null) 
235             return h;
236         
237         if (this.right != null) 
238             h = this.right.findpostOrder(no);
239         
240         if (h != null) 
241             return h;
242         
243         if (this.no == no) 
244             return this;
245         
246         return null;
247     
248 

 

以上是关于二叉树的主要内容,如果未能解决你的问题,请参考以下文章

二叉树及特殊二叉树(满二叉树完全二叉树二叉排序树平衡二叉树)的定义和性质(附详细推理过程)

二叉树二叉树的镜像

普通二叉树二叉查找树平衡二叉树常见操作汇总

SDUT 3341 数据结构实验之二叉树二:遍历二叉树

树二叉树满二叉树完全二叉树

SDUT 3341 数据结构实验之二叉树二:遍历二叉树