简介/定义
二叉树作为常用的数据结构之一,其特性再计算机领域被广泛应用,balabala...(自行查找)
偷个低清无码的图给各位看看:
二叉树存储结构
常见的二叉树存储可以是顺序存储,也可以是链表存储。
相关术语
树的结点:包含一个数据元素及若干指向子树的分支;
孩子结点:结点的子树的根称为该结点的孩子;
双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙;
结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
树的深度:树中最大的结点层;
结点的度:结点子树的个数;
树的度: 树中最大的结点度;
叶子结点:也叫终端结点,是度为 0 的结点;(重点)
分枝结点:度不为0的结点;
有序树:子树有序的树,如:家族树;
无序树:不考虑子树的顺序;
划重点
如果想要对二叉树有深入的理解,除了它的基本性质必须要了解,最重要的是要对递归有深入的了解,二叉树是递归定义的。
二叉树有以下三种类型:
(1)完全二叉树 -- 【若设二叉树的高度为h,除第 h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。】
(2)满二叉树 -- 【除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。】
(3)平衡二叉树 -- 【平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。】
在二叉树的基础上,或者修改或者增加不同的规则形成了各种各样的树,树形结构在开发中运用的相当广泛理解树的基本概念有助于理解很多原理,例如数据库的索引原理等,所以树的概念必须要清楚。
废话不多说,上代码:
**
*
* 类名称:Node.java <br>
* 内容摘要: //节点。<br>
* 修改备注: <br>
* 创建时间: 2018年5月8日下午2:30:30<br>
*
* @author Snoopy.Li<br>
*/
public class Node {
// 左节点
private Node left;
// 右节点
private Node right;
// 内容
private int data;
public Node(int data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
import java.util.Stack;
/**
*
* 类名称:BinaryTree.java <br>
* 内容摘要: //二叉树。<br>
* 修改备注: <br>
* 创建时间: 2018年5月8日上午10:25:58<br>
*
* @author Snoopy.Li<br>
*/
public class BinaryTree {
// 根节点
private Node root;
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
/**
* 递归构造二叉树
*
* @param node
* @param data
*/
public void buildTree(Node node, int data) {
if (root == null) {
// 根节点下面没有子节点,即根节点为叶子节点
root = new Node(data);
} else {
if (data < node.getData()) {
// 比父节点小的放到左边
if (node.getLeft() == null) {
// 父节点为叶子节点
node.setLeft(new Node(data));
} else {
// 父节点非叶子节点
buildTree(node.getLeft(), data);
}
} else {
// 比父节点大放到右边
if (node.getRight() == null) {
// 父节点为叶子节点
node.setRight(new Node(data));
} else {
// 父节点为非叶子节点
buildTree(node.getRight(), data);
}
}
}
}
/**
* 递归 先序遍历二叉树<br>
* 直接访问p指向的节点,然后访问该节点的左子树,最后访问节点的右子树。
*
* @param node
*/
public void preShow(Node node) {
if (node != null) {
System.out.print(node.getData() + " ");
preShow(node.getLeft());
preShow(node.getRight());
}
}
/**
* 非递归先序遍历二叉树
*/
public void preShow() {
Stack<Node> stack = new Stack<>();
Node node = root;
while ((node != null) || stack.empty() != true) {
if (node != null) {
// 打印根节点
System.out.print(node.getData() + " ");
// 将根节点压栈
stack.push(node);
node = node.getLeft();
} else {
// 当该节点为叶子节点时,弹栈
node = stack.pop();
node = node.getRight();
}
}
}
/**
* 递归 中序遍历二叉树<br>
* 先遍历节点的左子树,遍历完毕之后访问此节点,之后访问节点的右子树
*
* @param node
*/
public void inorderShow(Node node) {
if (node != null) {
inorderShow(node.getLeft());
System.out.print(node.getData() + " ");
inorderShow(node.getRight());
}
}
/**
* 非递归中序遍历二叉树
*/
public void inorderShow() {
Stack<Node> stack = new Stack<>();
Node node = root;
while (true) {
// 左子树压栈
while (node != null) {
stack.push(node);
node = node.getLeft();
}
if (stack.empty() == true) {
return;
}
node = stack.pop();
System.out.print(node.getData() + " ");
// 右子树压栈
node = node.getRight();
}
}
/**
* 递归 后序遍历二叉树<br>
* 先遍历节点的左子树,然后遍历节点的右子树,最后遍历该节点
*
* @param node
*/
public void posShow(Node node) {
if (node != null) {
posShow(node.getLeft());
posShow(node.getRight());
System.out.print(node.getData() + " ");
}
}
/**
* 非递归后序遍历二叉树
*/
public void posShow() {
Stack<Node> stack = new Stack<>();
// 构造一个中间栈来存储逆后续遍历的结果
Stack<Node> output = new Stack<Node>();
Node node = root;
while (node != null || stack.size() > 0) {
if (node != null) {
output.push(node);
stack.push(node);
node = node.getRight();
} else {
node = stack.pop();
node = node.getLeft();
}
}
while (output.size() > 0) {
System.out.print(output.pop().getData() + " ");
}
}
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
int[] sample = { 9, 5, 10, 25, 3, 4, 6, 1, 40, 29 };
for (int i = 0; i < sample.length; i++) {
binaryTree.buildTree(binaryTree.getRoot(), sample[i]);
}
System.out.print("递归先序遍历:[ ");
binaryTree.preShow(binaryTree.getRoot());
System.out.println("]");
System.out.print("非递归先序遍历:[ ");
binaryTree.preShow();
System.out.println("]");
System.out.print("递归中序遍历:[ ");
binaryTree.inorderShow(binaryTree.getRoot());
System.out.println("]");
System.out.print("非递归中序遍历:[ ");
binaryTree.inorderShow();
System.out.println("]");
System.out.print("递归后序遍历:[ ");
binaryTree.posShow(binaryTree.getRoot());
System.out.println("]");
System.out.print("非递归后序遍历:[ ");
binaryTree.posShow();
System.out.println("]");
}
}