二叉树常见类型

1、满二叉树

一棵二叉树的结点要么是叶子结点,要么它有两个子结点(如果一个二叉树的层数为K,且结点总数是(2^k) -1,则它就是满二叉树。)

java求二叉树宽度_java求二叉树宽度

层数与此层节点数的对应关系:第K层,节点数为2^(K)。K从0开始。

计算公式

java求二叉树宽度_List_02

等比数列求和公式

java求二叉树宽度_java中有二叉树类吗_03

最终得出

java求二叉树宽度_List_04

2、完全二叉树

若设二叉树的深度为k,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k 层所有的结点都连续集中在最左边,这就是完全二叉树。

java求二叉树宽度_java中有二叉树类吗_05

3、平衡二叉树

它或者是一颗空树,或它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

java求二叉树宽度_结点_06

4、二叉搜索树

它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树

java求二叉树宽度_java求二叉树宽度_07

5、 红黑树

平衡二叉搜索树

java求二叉树宽度_java求二叉树宽度_08

6、最优二叉树(哈夫曼树)

树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

注意点

感觉最常用的就是前5种,尤其是搜索二叉树,在进行树的相关操作时,需要利用树的定义来解题。

遍历方式

1.前序遍历

前序遍历(DLR,data,lchild,rchild),是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。

2.中序遍历

中序遍历(LDR)是 二叉树遍历的一种,也叫做 中根遍历、中序周游。在二叉树中,先左后根再右。

3.后序遍历

后序遍历(LRD)是 二叉树遍历的一种,也叫做 后根遍历、后序周游,先左后右再根。

4.层次遍历

与树的前中后序遍历的DFS思想不同,层次遍历用到的是BFS思想。一般DFS用递归去实现(也可以用栈实现),BFS需要用队列去实现。

层次遍历的步骤是:

1.对于不为空的结点,先把该结点加入到队列中

2.从队中拿出结点,如果该结点的左右结点不为空,就分别把左右结点加入到队列中

3.重复步骤2直到队列为空

import org.junit.Test;
import sun.reflect.generics.tree.Tree;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
/**
* @author shkstart
* @create 2021-03-03 10:49
*/
public class BinaryTree {
/**
* 生成一个满二叉树(也是搜索二叉树)
* @return
*/
public TreeNode[] createBinaryTree(){
TreeNode[] node =new TreeNode[15];
for(int i=0; i
node[i] = new TreeNode(i);
}
for(int i=0;(2*i+1)
node[i].left = node[2*i+1];
if(2*i+2< node.length){
node[i].right = node[2*i+2];
}
}
return node;
}
/**
* 递归前序遍历
* @return
*/
public List preOrder(TreeNode root,List res){
if(root==null) return null;
res.add(root);
preOrder(root.left,res);
preOrder(root.right,res);
return res;
}
/**
* 递归中序遍历
* @param root
* @param res
* @return
*/
public List inOrder(TreeNode root, List res){
if(root==null) return null;
inOrder(root.left,res);
res.add(root);
inOrder(root.right,res);
return res;
}
/**
* 递归后序遍历
* @param root
* @param res
* @return
*/
public List lastOrder(TreeNode root, List res){
if(root==null) return null;
lastOrder(root.left,res);
lastOrder(root.right,res);
res.add(root);
return res;
}
/**
* 层序遍历BFS
* @param root
* @return
*/
public List> layerOrder(TreeNode root){
if(root==null){ return null; }
List> res = new ArrayList<>();
Queue queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
List tmp = new LinkedList<>();
for(int n = queue.size();n>0;n--){
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left!=null){ queue.add(node.left); }
if(node.right!=null){ queue.add(node.right); }
}
res.add(tmp);
}
return res;
}
@Test
public void Test1()
{
System.out.println("-------创建满二叉树-------");
TreeNode[] binaryTree = createBinaryTree();
for(TreeNode node: binaryTree){
System.out.print(node.val+" ");
}
System.out.println(" ");
System.out.println("------前序遍历--------");
List resPre = new LinkedList<>();
List treeNodePre = preOrder(binaryTree[0],resPre);
for(TreeNode node: treeNodePre){
System.out.print(node.val+" ");
}
System.out.println("");
System.out.println("-------中序遍历-------");
List resMid = new LinkedList<>();
List treeNodesMid = inOrder(binaryTree[0],resMid);
for(TreeNode node: treeNodesMid){
System.out.print(node.val+" ");
}
System.out.println("");
System.out.println("-------后序遍历-------");
List resLast = new LinkedList<>();
List treeNodesLast = lastOrder(binaryTree[0],resLast);
for(TreeNode node: treeNodesLast){
System.out.print(node.val+" ");
}
System.out.println("");
System.out.println("-------层序遍历-------");
List> treeNodesLayer = layerOrder(binaryTree[0]);
for (List list : treeNodesLayer) {
for (Object o : list) {
System.out.print(o+" ");
}
System.out.println(" ");
}
}
}

之后有关树的相关知识将会在本博客持续更新~,暂时先写这么多。