# 二叉树
每个结点的度 均不超过 2 的 有序 树,称为 二叉树(binary tree)
二叉查找/ 搜索/ 排序树 BST (binary search/sort tree) 或者是一棵空树; 或者是具有下列性质的二叉树: (1)若它的左子树不空,则左子树上所有结点的值均小于 它的根节点的值; (2)若它的右子树上所有结点的值均大于它的根节点的值; (3)它的左、右子树也分别为二叉排序树。
平衡二叉树 (Self-balancing binary search tree ) 自 平衡二叉查找树 又被称为 AVL 树( 有别于 AVL 算法) 它是一 棵空树 或它的左右两个子树的高度差( 平衡因子 )的绝对值不超过 1 平衡二叉树: 每个结点的平衡因子都为 1、-1、0 的二 叉排序树。或者说每个结点的左右子树的高度最多差 1 的二 叉排序树。 平衡二叉树的目的是为了减少二叉查找树层次,提高查找速 度
红黑树 R-B Tree,全称是 Red-Black Tree,又称为"红黑树",它 一种平衡二叉树。红黑树的每个节点上都有存储位表示节点 的颜色,可以是红(Red)或黑(Black)。 红黑树的特性: (1)每个节点或者是黑色,或者是红色。 (2)根节点是黑色。 (3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点, 是指为空(NIL 或 NULL)的叶子节点!] (4)如果一个节点是红色的,则它的子节点必须是黑色的。 (5)从一个节点到该节点的子孙节点的所有路径上包含相 同数目的黑节点。 注意: (01) 特性(3)中的叶子节点,是只为空(NIL 或 null)的节点。 (02) 特性(5),确保没有一条路径会比其他路径长出俩倍。因 而,红黑树是相对是接近平衡的二叉树
相比数组和链表,二叉树是一种比较独特的数据结构,树是一种非线性的数据结构,相对于线性的数据结构(链表、数组)而言,树的平均运行时间更短(往往与树相关的排序时间复杂度都不会高) 我们先来研究简单又经常用的---> 二叉树 1
二叉树是由根节点N,左孩子节点L,右孩子节点R组成,那么这三个节点一共有 6 种排序方式,而实际上只有 3 种,另外 3 种只是顺序倒过来而已。这三种排序方式是: NLR、LNR、LRN,分别对应 先根、中根、后根遍历,先根即 N 在最前,中跟即 N 在中间,后根即 N 在最后。
首先创建二叉树节点
/**
* 二叉树节点
* @param <T>
*/
public class TreeNode<T> {
//节点的属性-角标、数据、左节点、右节点
private int index;
private T data;
private TreeNode leftChild;
private TreeNode rightChild;
//初始化节点
public TreeNode(int index, T data) {
this.index = index;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
//getter,setter
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public TreeNode getLeftChild() {
return leftChild;
}
public void setLeftChild(TreeNode leftChild) {
this.leftChild = leftChild;
}
public TreeNode getRightChild() {
return rightChild;
}
public void setRightChild(TreeNode rightChild) {
this.rightChild = rightChild;
}
}
创建二叉树
/**
* 创建二叉树
* @author yk
*/
public class BinaryTree {
public TreeNode root = null;
//用构造函数初始化根节点
public BinaryTree() {
root = new TreeNode<>(1, "A");
}
public void createBinaryTree() {
TreeNode nodeB = new TreeNode<>(1, "B");
TreeNode nodeC = new TreeNode<>(1, "C");
TreeNode nodeD = new TreeNode<>(1, "D");
TreeNode nodeE = new TreeNode<>(1, "E");
TreeNode nodeF = new TreeNode<>(1, "F");
TreeNode nodeG = new TreeNode<>(1, "G");
root.setLeftChild(nodeB);
root.setRightChild(nodeC);
nodeB.setLeftChild(nodeD);
nodeB.setRightChild(nodeE);
nodeC.setLeftChild(nodeF);
nodeC.setRightChild(nodeG);
}
//获取二叉树的高度
public int getHeight() {
return getHeight(root);
}
public int getHeight(TreeNode node) {
if (node == null) {
return 0;
}
int leftHeight = getHeight(node.getLeftChild());
int rightHeight = getHeight(node.getRightChild());
return leftHeight > rightHeight ? (leftHeight + 1) : (rightHeight + 1);
}
//获取二叉树的大小
public int getSize() {
return getSize(root);
}
public int getSize(TreeNode node) {
if (node == null) {
return 0;
}
int leftSize = getSize(node.getLeftChild());
int rightSize = getSize(node.getRightChild());
return leftSize + rightSize + 1;
}
//先序遍历
public void beforeOrder(TreeNode node) {
if (node == null) {
return;
}
System.out.print(node.getData() + " ");
beforeOrder(node.getLeftChild());
beforeOrder(node.getRightChild());
}
//中序遍历
public void midOrder(TreeNode node) {
if (node == null) {
return;
}
midOrder(node.getLeftChild());
System.out.print(node.getData() + " ");
midOrder(node.getRightChild());
}
//后序遍历
public void afterOrder(TreeNode node) {
if (node == null) {
return;
}
afterOrder(node.getLeftChild());
afterOrder(node.getRightChild());
System.out.print(node.getData() + " ");
}
}