二叉树的构建规则:
左子树上的值均不大于右子树,所以在生成插入的时候,需要以下几步
- 判断根节点是否为空,不为空,则直接根节点就是插入节点
- 若根节点不为空,判断值与根节点大小相比,若大于,则递归插入右子树,节点变为根节点的右子树,反之则插入左子树。
- 插入的时候,若是递归插入,需要传入根节点,以及值。
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
插入节点功能实现:
static void insert(TreeNode tree, int val) {
if (tree == null) {
tree.val = val;
} else {
if (tree.val > val) {
if (tree.left == null) {
tree.left = new TreeNode(val);
} else {
insert(tree.left, val);
}
} else {
if (tree.right == null) {
tree.right = new TreeNode(val);
} else {
insert(tree.right, val);
}
}
}
前序遍历递归实现:
static void preOrder(TreeNode tree) {
if (tree == null) {
return;
}
System.out.println(tree.val);
preOrder(tree.left);
preOrder(tree.right);
}
前序非递归实现:
- 由于前序遍历是按照中-左-右的顺序遍历,所以用到栈这种结构,可以实现先进后出的功能,与递归一样,递归的数据也是保存在栈中。
- 首先输出根节点数据,然后将根节点压栈,节点变为左节点,重复直到在最底层的最左边。
- 在最左边后,弹出栈,节点变成弹出节点的右边子树,继续执行步骤2
- 直到最底层的最右边弹出完成,栈为空,退出循环。
static void preOrder2(TreeNode tree) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = tree;
while (node != null || !stack.empty()) {
while (node != null) {
System.out.println(node.val);
stack.push(node);
node = node.left;
}
if (!stack.empty()) {
node = stack.pop();
node = node.right;
}
}
}
中序遍历与前序相似,代码在最后展示。
层次遍历:
- 层次遍历过程是一个逐步向后的过程,有着先进行先输出的特性,所以用队列来实现这个过程,在java中可以通过继承LinkedList来实现队列。当然也可以直接用LinkedList来实例化对象。
- 首先还是将根节点放入队头
- 判断队列是否为空,如果不为空,将队头出队,并打印相关值,然后判断左右子树是否有,若有,则入队。
- 重复这个过程,直到队列中所有值都出队了,队列为空,此时可以结束循环。
static void floor(TreeNode tree) {
Queue<TreeNode> quene = new LinkedList<>();
quene.add(tree);
while (!quene.isEmpty()) {
tree = quene.poll(); //出队
System.out.print(tree.val + " ");
if (tree.left != null) {
quene.add(tree.left); //入队
}
if (tree.right != null) {
quene.add(tree.right);
}
}
}
所有代码实现,main函数所在类为DF
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
//二叉树实现
class TreeNode {
int val;
TreeNode left;
TreeNode right;
// 构造函数
public TreeNode(int val) {
this.val = val;
}
//插入节点
static void insert(TreeNode tree, int val) {
if (tree == null) {
tree.val = val;
} else {
//如果小于根节点,放在左子树上
if (tree.val > val) {
if (tree.left == null) {
tree.left = new TreeNode(val);
} else {
insert(tree.left, val);
}
//如果大于根节点,放在右子树上
} else {
if (tree.right == null) {
tree.right = new TreeNode(val);
} else {
insert(tree.right, val);
}
}
}
}
//前序遍历,递归实现
static void preOrder(TreeNode tree) {
if (tree == null) {
return;
}
// 中-左-右
System.out.println(tree.val);
preOrder(tree.left);
preOrder(tree.right);
}
//前序遍历,非递归实现
static void preOrder2(TreeNode tree) {
// 栈实现
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = tree;
while (node != null || !stack.empty()) {
while (node != null) {
System.out.println(node.val);
stack.push(node);
// 入栈,替换根节点为左节点
node = node.left;
}
if (!stack.empty()) {
// 出栈,替换根节点为右边
node = stack.pop();
node = node.right;
}
}
}
//中序遍历,可以排序输出
static void midOrder(TreeNode tree) {
if (tree == null) {
return;
}
// 左-中-右
midOrder(tree.left);
System.out.println(tree.val);
midOrder(tree.right);
}
//中序遍历非递归实现
static void midOrder2(TreeNode tree) {
Stack<TreeNode> stack = new Stack<>();
while (tree != null || !stack.empty()) {
while (tree != null) {
stack.push(tree);
tree = tree.left;
}
if (!stack.isEmpty()) {
tree = stack.pop();
System.out.println(tree.val);
tree = tree.right;
}
}
}
//层次遍历
static void floor(TreeNode tree) {
// 队列实现或者链表实现
Queue<TreeNode> quene = new LinkedList<>();
quene.add(tree);
while (!quene.isEmpty()) {
tree = quene.poll();
System.out.print(tree.val + " ");
if (tree.left != null) {
quene.add(tree.left);
}
if (tree.right != null) {
quene.add(tree.right);
}
}
}
}
public class DF {
public static void main(String[] args) {
// TODO Auto-generated method stub
//二叉树实例化
TreeNode tree = new TreeNode(10);
// int a[] = new int[10];
int a[] = { 5, 20, 3, 6, 21, 25 };
for (int i = 0; i < a.length; i++) {
// a[i] = (int) Math.floor(Math.random() * 100);
tree.insert(tree, a[i]);
//插入二叉树中
}
tree.floor(tree);
// tree.midOrder(tree);
// tree.midOrder(tree);
// tree.midOrder2(tree);
}
层次遍历结果:10 5 20 3 6 21 25
中序遍历: 3 5 6 10 20 21 25
前序遍历: 10 5 3 6 20 21 25