二叉树
树:除根结点外,所有结点都有唯一的父结点,是一对多的关系。
二叉树的递归定义:
- 如果没有根结点,则是一颗空树;
- 如果有根结点,则二叉树由根结点、左子树、右子树组成,并且左子树和右子树都是二叉树。
注意:在二叉树是严格区分左右子树的,如果交互左右子树,就变成了另一棵二叉树。
二叉树的深度遍历:
深度遍历二叉树的递归实现:
- 如果当前结点为null,则返回;
- 当前结点不为null,深度遍历左子树,然后深度遍历右子树。
二叉树的三种遍历方式:
先序遍历:访问根结点,再遍历左子树,最后遍历右子树。
中序遍历:先遍历左子树,再访问根结点,最后遍历右子树。
后序遍历:先遍历左子树,再遍历右子树,最后访问根结点。
代码:
package day09;
/**
* Binary tree with char type elements.
*
* @author Zhong Xiyan 976078956@qq.com
*/
public class BinaryCharTree {
/**
* The value in char.
*/
char value;
/**
* The left child.
*/
BinaryCharTree leftChild;
/**
* The right child.
*/
BinaryCharTree rightChild;
/**
*
*********************
* The first constructor.
*
* @param paraName The value.
*********************
*
*/
public BinaryCharTree(char paraName) {
value = paraName;
leftChild = null;
rightChild = null;
}// Of the constructor
/**
*
*********************
* @Title: manualConstructTree
* @Description: TODO(Manually construct a tree. Only for testing.)
*
* @return A binary tree.
*********************
*/
public static BinaryCharTree manualConstructTree() {
// Step 1. Construct a tree with only one node.
BinaryCharTree resultTree = new BinaryCharTree('a');
// Step 2. Construct all nodes. The first node is the root.
BinaryCharTree tempTreeB = new BinaryCharTree('b');
BinaryCharTree tempTreeC = new BinaryCharTree('c');
BinaryCharTree tempTreeD = new BinaryCharTree('d');
BinaryCharTree tempTreeE = new BinaryCharTree('e');
BinaryCharTree tempTreeF = new BinaryCharTree('f');
BinaryCharTree tempTreeG = new BinaryCharTree('g');
// Step 3. Link all nodes.
resultTree.leftChild = tempTreeB;
resultTree.rightChild = tempTreeC;
tempTreeB.rightChild = tempTreeD;
tempTreeC.leftChild = tempTreeE;
tempTreeD.leftChild = tempTreeF;
tempTreeD.rightChild = tempTreeG;
return resultTree;
}// Of manualConstructTree
/**
*
*********************
* @Title: preOrderVisit
* @Description: TODO(Pre-order visit.)
*
*********************
*
*/
public void preOrderVisit() {
System.out.print("" + value + " ");
if (leftChild != null) {
leftChild.preOrderVisit();
} // Of if
if (rightChild != null) {
rightChild.preOrderVisit();
} // Of if
}// Of preOderVisit
/**
*
*********************
* @Title: inOrderVisit
* @Description: TODO(In-order visit.)
*
*********************
*
*/
public void inOrderVisit() {
if (leftChild != null) {
leftChild.inOrderVisit();
} // Of if
System.out.print("" + value + " ");
if (rightChild != null) {
rightChild.inOrderVisit();
} // Of if
}// Of inOrderVisit
/**
*
*********************
* @Title: postOrderVisit
* @Description: TODO(Post-order visit.)
*
*********************
*
*/
public void postOrderVisit() {
if (leftChild != null) {
leftChild.postOrderVisit();
} // Of if
if (rightChild != null) {
rightChild.postOrderVisit();
} // Of if
System.out.print("" + value + " ");
}// Of postOrderVisit
/**
*
*********************
* @Title: getDepth
* @Description: TODO(Get the depth of the binary tree.)
*
* @return The depth of the tree.
*********************
*
*/
public int getDepth() {
// It is a leaf.
if (leftChild == null && rightChild == null) {
return 1;
} // Of if
// Get the depth both of left child and right child. 0 for without the child.
int leftDepth = 0, rightDepth = 0;
if (leftChild != null) {
leftDepth = leftChild.getDepth() + 1;
} // Of if
if (rightChild != null) {
rightDepth = rightChild.getDepth() + 1;
} // Of if
return leftDepth > rightDepth ? leftDepth : rightDepth;
}// Of getDepth
/**
*
*********************
* @Title: getNumNodes
* @Description: TODO(Get the number of nodes)
*
* @return The number of nodes.
*********************
*
*/
public int getNumNodes() {
// It is a leaf.
if (leftChild == null && rightChild == null) {
return 1;
} // Of if
int leftChildNodes = 0, rightChildNodes = 0;
// Get the number of nodes of the left child.
if (leftChild != null) {
leftChildNodes = leftChild.getNumNodes();
} // Of if
// Get the number of nodes of the right child.
if (rightChild != null) {
rightChildNodes = rightChild.getNumNodes();
} // Of if
// The total number of nodes.
return leftChildNodes + rightChildNodes + 1;
}//Of getNumNodes
public static void main(String args[]) {
BinaryCharTree tempTree = manualConstructTree();
System.out.println("\r\nPreorder visit:");
tempTree.preOrderVisit();
System.out.println("\r\nInorder visit:");
tempTree.inOrderVisit();
System.out.println("\r\nPostorder visit:");
tempTree.postOrderVisit();
System.out.println("\r\n\r\nThe depth is: " + tempTree.getDepth());
System.out.println("The number of nodes is: " + tempTree.getNumNodes());
}// Of main
}// Of class BinaryCharTree
代码生成的二叉树:
运行结果:
总结:对二叉树的特点和操作这些理解都还算到位,但今天在写代码的时候,明显感觉到了大脑会了,手还不会的尴尬局面。由于以前写代码的时候,大部分都是面向过程的,现在对面向对象的代码思维还不是很习惯,所以卡顿了一会儿。