您的位置:首页 > 其它

二叉树相关算法——创建、遍历、求深度和广度

2017-11-18 23:31 381 查看
二叉树相关的算法,遍历使用了递归和迭代两种算法,可作为结果对比。

理解起来不难,直接上代码,有空再补下注释说明原理。

package com.junyang.algodemo.Tree;

import java.util.LinkedList;
import java.util.Stack;

public class TreeUtil {
private static final int DEEP = 5;

/* 创建一个深度为deep的满二叉树,目的是为验证其它算法 */
public static TreeNode createTree(int deep) {
/* 处理deep为0 和为1的特殊情况 */
if (0 >= deep) {
return null;
}

int count = 0;
TreeNode root = new TreeNode(count++);
if (1 == deep) {
return root;
}

/* 满二叉树创建完成的条件为,当前这一层达到2的 deep-1 次方 */
double maxLayerNum = Math.pow(2f, deep - 1f);

TreeNode last = root;

/* 通过队列按层创建二叉树 */
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
int width = 0;

while (!queue.isEmpty()) {
TreeNode temp = queue.remove();
temp.left = new TreeNode(count++);
temp.right = new TreeNode(count++);

queue.add(temp.left);
queue.add(temp.right);
width += 2;

if (width == maxLayerNum) {
return root;
}

if (temp == last) {
last = last.right;
width = 0;
}
}

return root;
}

/* 按层遍历同時按行显示 */
public static void printTreeForLayer(TreeNode root) {
if (null == root) {
return;
}

LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
TreeNode last = root;
TreeNode nlast = root;
int lineNum = 1;

System.out.print("num[" + lineNum++ + "]:");
while (!queue.isEmpty()) {
TreeNode temp = queue.remove();

if (null != temp.left) {
queue.add(temp.left);
nlast = temp.left;
}

if (null != temp.right) {
queue.add(temp.right);
nlast = temp.right;
}

System.out.print(temp.data + " ");
if (temp == last) {
System.out.println();
if (!queue.isEmpty()) {
System.out.print("num[" + lineNum++ + "]:");
}
last = nlast;
}
}
}

/* 先序遍历 —— 递归 */
public static void printTreeForRootFirst1(TreeNode root) {
if (root == null) {
return;
}

System.out.print(root.data + " ");
printTreeForRootFirst1(root.left);
printTreeForRootFirst1(root.right);

}

/* 先序遍历 —— 迭代*/
public static void printTreeForRootFirst2(TreeNode root) {
if (null == root) {
return;
}

Stack<TreeNode> stack = new Stack<>();
stack.push(root);

while (!stack.isEmpty()) {
TreeNode top = stack.pop();
System.out.print(top.data + " ");

if (top.right != null) {
stack.push(top.right);
}

if (top.left != null) {
stack.push(top.left);
}
}
}

/* 中序遍历 —— 递归 */
public static void printTreeForRootMiddle(TreeNode root) {
if (root == null) {
return;
}

printTreeForRootMiddle(root.left);
System.out.print(root.data + " ");
printTreeForRootMiddle(root.right);

}

/* 中序遍历 —— 迭代 */
public static void printTreeForRootMiddle2(TreeNode root) {
if (root == null) {
return;
}

Stack<TreeNode> stack = new Stack<>();

TreeNode cur = root;
while (!stack.isEmpty() || cur != null) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
cur = stack.pop();
System.out.print(cur.data + " ");
cur = cur.right;
}
}
}

/* 后序遍历 —— 递归 */
public static void printTreeForRootLast(TreeNode root) {
if (root == null) {
return;
}

printTreeForRootLast(root.left);
printTreeForRootLast(root.right);
System.out.print(root.data + " ");

}

/* 后序遍历 —— 迭代 */
public static void printTreeForRootLast2(TreeNode root) {
if (root == null) {
return;
}

Stack<TreeNode> stack = new Stack<>();
Stack<TreeNode> output = new Stack<>();

stack.push(root);
while (!stack.isEmpty()) {
TreeNode temp = stack.pop();
output.push(temp);

if (null != temp.left) {
stack.push(temp.left);
}

if (null != temp.right) {
stack.push(temp.right);
}
}

while (!output.isEmpty()) {
System.out.print(output.pop().data + " ");
}
}

/* 获取二叉树的宽度 */
public static int getWidth(TreeNode root) {
if (null == root) {
return 0;
}

int maxWidth = 1;
int curWidth = 0;
LinkedList<TreeNode> linkedList = new LinkedList<>();
linkedList.add(root);

TreeNode last = root;
TreeNode nlast = root;
while (!linkedList.isEmpty()) {
TreeNode temp = linkedList.remove();

if (null != temp.left) {
linkedList.add(temp.left);
nlast = temp.left;
curWidth++;
}

if (null != temp.right) {
linkedList.add(temp.right);
nlast = temp.right;
curWidth++;
}

if (temp == last) {
last = nlast;
maxWidth = maxWidth > curWidth ? maxWidth : curWidth;
curWidth = 0;
}
}

return maxWidth;
}

/* 获取二叉树的深度 */
public static int getDeep(TreeNode root) {
if (null == root) {
return 0;
}

int leftDeep = 0;
if (root.left != null) {
leftDeep = getDeep(root.left);
}

int rightDeep = 0;
if (root.right != null) {
rightDeep = getDeep(root.right);
}

return (rightDeep > leftDeep ? rightDeep : leftDeep) + 1;
}

public static void main(String[] args) {
TreeNode root = createTree(DEEP);
System.out.println("按层遍历");
printTreeForLayer(root);

System.out.println("先序遍历");
printTreeForRootFirst1(root);
System.out.println();
printTreeForRootFirst2(root);
System.out.println();

System.out.println("中序遍历");
printTreeForRootMiddle(root);
System.out.println();
printTreeForRootMiddle2(root);
System.out.println();

System.out.println("后序遍历");
printTreeForRootLast(root);
System.out.println();
printTreeForRootLast2(root);
System.out.println();

System.out.println("deep:" + getDeep(root));
System.out.println("width:" + getWidth(root));
}
}


输出:

按层遍历
num[1]:0
num[2]:1 2
num[3]:3 4 5 6
num[4]:7 8 9 10 11 12 13 14
num[5]:15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
先序遍历
0 1 3 7 15 16 8 17 18 4 9 19 20 10 21 22 2 5 11 23 24 12 25 26 6 13 27 28 14 29 30
0 1 3 7 15 16 8 17 18 4 9 19 20 10 21 22 2 5 11 23 24 12 25 26 6 13 27 28 14 29 30
中序遍历
15 7 16 3 17 8 18 1 19 9 20 4 21 10 22 0 23 11 24 5 25 12 26 2 27 13 28 6 29 14 30
15 7 16 3 17 8 18 1 19 9 20 4 21 10 22 0 23 11 24 5 25 12 26 2 27 13 28 6 29 14 30
后序遍历
15 16 7 17 18 8 3 19 20 9 21 22 10 4 1 23 24 11 25 26 12 5 27 28 13 29 30 14 6 2 0
15 16 7 17 18 8 3 19 20 9 21 22 10 4 1 23 24 11 25 26 12 5 27 28 13 29 30 14 6 2 0
deep:5
width:16
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐