写在前面:
二叉树(Binary Tree)
特点:每个结点至多有两棵子树(即二叉树中不存在度大于2的结点),且二叉树的子树有左右之分,左子树和右子树不可颠倒。
二叉树的相关操作:
--遍历:(N:Node L:LeftSubTree R:RightSubTree)
遍历其实是将二叉树每一个结点按照线性排列的过程。
前序遍历:NLR--根左右
中序遍历:LNR--左根右
后序遍历:LRN--左右根
举例:
比如中序遍历的结果是:(8的左子树)8(8的右子树),而对于8的左子树,以3为根结点,再进行中序遍历=(3的左子树)3(3的右子树),依次类推,那么8的左子树就=1,3,4,6,7。对于8的右子树,以10为根节点进行中序遍历,那么8的右子树=10,13,14,所以最后,中序遍历的结果,就是1,3,4,6,7,8,10,13,14.
接下来,我们来看一下前序遍历,中序遍历,后序遍历的程序实现。
程序实现:
package tree;
import java.util.Stack;
public class BinaryTree {
private TreeNode root = null;
public BinaryTree() {
//设置根节点
root = new TreeNode(1, "rootNodeA");
}
private static class TreeNode {
private int key;
private String data = null;
private TreeNode leftchild;
private TreeNode rightchild;
public TreeNode(int key, String data) {
this.key = key;
this.data = data;
this.leftchild = null;
this.rightchild = null;
}
public static TreeNode getParent(TreeNode subTree, TreeNode element) {
if (subTree == null) {
return null;
}
if (subTree.leftchild == element || subTree.rightchild == element) {
return subTree;
}
TreeNode p;
if ((p = getParent(subTree.leftchild, element)) != null) {
return p;
} else {
return getParent(subTree.rightchild, element);
}
}
}
public void createBinTree(TreeNode root) {
/**
* 结构: A
* B C */ D E F
TreeNode nodeB = new TreeNode(2, "nodeB");
TreeNode nodeC = new TreeNode(3, "nodeC");
TreeNode nodeD = new TreeNode(4, "nodeD");
TreeNode nodeE = new TreeNode(5, "nodeE");
TreeNode nodeF = new TreeNode(6, "nodeF");
root.leftchild = nodeB;
root.rightchild = nodeC;
nodeB.leftchild = nodeD;
nodeB.rightchild = nodeE;
nodeC.rightchild = nodeF;
}
public TreeNode getRoot() {
return this.root;
}
public boolean isEmpty() {
return root == null;
}
public int height() {
return height(this.root);
}
/**
* 树的高度
* @param subTree
* @return
*/
public int height(TreeNode subTree) {
if (subTree == null) {
return 0;
} else {
int i = height(subTree.leftchild);
int j = height(subTree.rightchild);
return (i < j) ? (j + 1) : (i + 1);
}
}
/**
* 树中结点的个数
* @return
*/
public int size() {
return size(this.root);
}
public int size(TreeNode subTree) {
if (subTree == null) {
return 0;
} else {
return 1 + size(subTree.leftchild) + size(subTree.rightchild);
}
}
public TreeNode Parent(TreeNode element) {
return (root == null || root == element) ? null : TreeNode.getParent(root, element);
}
public TreeNode getLeftChildNode(TreeNode element) {
return (element != null) ? element.leftchild : null;
}
public TreeNode getRightChildNode(TreeNode element) {
return (element != null) ? element.rightchild : null;
}
public static void visted(TreeNode subTree) {
System.out.println("data: " + subTree.data);
}
/**
* 前序遍历的递归实现
* @param subTree
*/
public static void preOrder(TreeNode subTree) {
if (subTree != null) {
visted(subTree);
preOrder(subTree.leftchild);
preOrder(subTree.rightchild);
}
}
/**
* 中序遍历的递归实现
* @param subTree
*/
public static void inOrder(TreeNode subTree) {
if (subTree != null) {
inOrder(subTree.leftchild);
visted(subTree);
inOrder(subTree.rightchild);
}
}
/**
* 后序遍历的递归实现
* @param subTree
*/
public static void postOrder(TreeNode subTree) {
if (subTree != null) {
postOrder(subTree.leftchild);
postOrder(subTree.rightchild);
visted(subTree);
}
}
/**
* 前序遍历的非递归实现
* @param p
*/
public void nonRecPreOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = p;
while (node != null || stack.size() > 0) {
while (node != null) {
visted(node);
stack.push(node);
node = node.leftchild;
}
if (stack.size() > 0) {
node = stack.pop();
node = node.rightchild;
}
}
}
/**
* 中序遍历的非递归实现
* @param p
*/
public void nonRecInOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = p;
while (node != null || stack.size() > 0) {
while (node != null) {
stack.push(node);// 保存左子树
node = node.leftchild;
}
if (stack.size() > 0) {
node = stack.pop();
visted(node);
node = node.rightchild;
}
}
}
/**
* 后序遍历的非递归实现
* @param p
*/
public void nonRecPostOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = p;
while (p != null) {
for (; p.leftchild != null; p = p.leftchild) {
stack.push(p);
}
while (p != null && (p.rightchild == null || p.rightchild == node)) {
visted(p);
node = p;
if (stack.empty())
return;
p = stack.pop();
}
// 处理右子树
stack.push(p);
p = p.rightchild;
}
}
/**
* 释放某一个结点
* 左子树,右子树都要释放
* @param subTree
*/
public static void destory(TreeNode subTree) {
if (subTree != null) {
destory(subTree.leftchild);
destory(subTree.rightchild);
subTree = null;
}
}
}
总结:
二叉树的基础就是二叉树的三种遍历方式,在接下里的文章还会为各位读者介绍二叉树的镜像,层次遍历等。如果文章中有疏漏请大家在评论中指出,楼主会不胜感激,最后希望我的文章会对你有所帮助,谢谢大家。