名词
根节点(root)
中间节点(internal node)
叶节点(leaf node)
祖先(ancestors)
后代,继承人(descendants)
深度(depth) 从0开始,如图所示的d节点的depth = 2 b节点的depth = 0
高度(height)从0开始,如图所示的树height = 2
三种遍历方法
1. 先序遍历(preorder)类似于搜索算法中的深度优先搜索,先访问这个点的根节点,然后再去访问他的所有子节点,需把他的所有子节点访问完。如图所示,则他的先序遍历为b a d f c e
2. 后序遍历(postorder)先遍历子节点再遍历父母节点,如图所示,则他的后序遍历为d f a c e b
3. 中序遍历(inorder)直接做垂直映射即可,但是只针对二叉树有效(binary tree)
二叉树的结构
每个二叉树节点有以下属性:node.value node.left node.right node.parent如图所示
如果一个节点的left和right都为null,则该节点为叶子节点
二叉树的存储
1. 一维数组存储
缺点:1.浪费空间 2.插入删除浪费时间
2. 链表存储(通常选择这个方式)
特殊的二叉树(完全二叉树)
完全二叉树是一颗特殊的二叉树,它遵循以下规则:假设完全二叉树高度为k,则完全二叉树需要符合以下两点:
1)所有叶子节点都出现在k层或k-1层,并且从1~k-1层必须达到最大节点数。
2)第k层可以是不满的,但是第k层的所有节点必须集中在最左边
如下图所示:
二叉树的单个节点实现
class TreeNode
{
String data;
TreeNode leftchild;
TreeNode rightchild;
TreeNode parent;
TreeNode()
{
data = "";
leftchild = null;
leftchild = null;
leftchild = null;
}
TreeNode(String value)
{
data = value;
leftchild = null;
leftchild = null;
leftchild = null;
}
TreeNode(String value,TreeNode left,TreeNode right,TreeNode p)
{
data = value;
leftchild = left;
rightchild = right;
parent = p;
}
public void setLeftChild(TreeNode left)
{
leftchild = left;
}
public void setRightChild(TreeNode right)
{
rightchild = right;
}
public void setParent(TreeNode p)
{
parent = p;
}
public void setData(String value)
{
data = value;
}
}
二叉树的实现(通常来说只有一个根节点,然后不断增加)
二叉树需要的常用接口:
1. 求一个二叉树的高度:首先需要一种获取以某个节点为子树的高度方法,使用递归实现。如果根节点为空,那么这个节点肯定是一颗空树,高度为0;如果不为空,则遍历地比较它的左右子树高度,高的一个为这颗子树的最大高度,然后加上自身的高度即可
public int getHeight(TreeNode node)
{
int treeHeight = 0;
if (node == null)
{
treeHeight = 0;
}
else
{
int leftHeight = getHeight(node.leftchild);
int rightHeight = getHeight(node.rightchild);
if (leftHeight >= rightHeight)
{
treeHeight = leftHeight + 1;
}
else
{
treeHeight = rightHeight + 1;
}
}
return treeHeight;
}
2. 递归先序遍历
public void preOrder(TreeNode node)
{
if (node != null)
{
System.out.println(node.data);
preOrder(node.leftchild);
preOrder(node.rightchild);
}
}
3. 递归中序遍历
public void inOrder(TreeNode node)
{
if (node != null)
{
inOrder(node.leftchild);
System.out.println(node.data);
inOrder(node.rightchild);
}
}
4. 递归后序遍历
public void postOrder(TreeNode node)
{
if (node != null)
{
postOrder(node.leftchild);
postOrder(node.rightchild);
System.out.println(node.data);
}
}
二叉树整体实现
public class BinaryTree {
TreeNode root;
BinaryTree()
{
this.root = null;
}
BinaryTree(TreeNode node)
{
this.root = node;
}
public void setRoot(TreeNode node)
{
this.root = node;
}
public TreeNode getRoot()
{
return root;
}
public void insertLeft(TreeNode node,TreeNode newnode)
{
node.setLeftChild(newnode);
newnode.setParent(node);
}
public void insertRight(TreeNode node,TreeNode newnode)
{
node.setRightChild(newnode);
newnode.setParent(node);
}
public int getHeight(TreeNode node)
{
int treeHeight = 0;
if (node == null)
{
treeHeight = 0;
}
else
{
int leftHeight = getHeight(node.leftchild);
int rightHeight = getHeight(node.rightchild);
if (leftHeight >= rightHeight)
{
treeHeight = leftHeight + 1;
}
else
{
treeHeight = rightHeight + 1;
}
}
return treeHeight;
}
public void preOrder(TreeNode node)
{
if (node != null)
{
System.out.println(node.data);
preOrder(node.leftchild);
preOrder(node.rightchild);
}
}
public void inOrder(TreeNode node)
{
if (node != null)
{
inOrder(node.leftchild);
System.out.println(node.data);
inOrder(node.rightchild);
}
}
public void postOrder(TreeNode node)
{
if (node != null)
{
postOrder(node.leftchild);
postOrder(node.rightchild);
System.out.println(node.data);
}
}
public static void main(String[] args)
{
TreeNode root = new TreeNode("a");
TreeNode nodea = new TreeNode("b");
TreeNode nodeb = new TreeNode("c");
TreeNode nodec = new TreeNode("d");
BinaryTree bt = new BinaryTree(root);
bt.insertLeft(root, nodea);
bt.insertRight(root, nodeb);
bt.preOrder(bt.root);
bt.inOrder(bt.root);
bt.postOrder(bt.root);
System.out.println(bt.getHeight(bt.root));
}
}