1.实现二叉树的深度遍历(java)
(递归实现)
package cetc.tree.test;
import cetc.tree.test.BinaryTree2.TreeNode;
public class BinaryTree2 {
/**
* 定义一个二叉树的节点
* @author Administrator
*
*/
public class TreeNode {
int data;
TreeNode left;
TreeNode right;
public TreeNode(int data, TreeNode left, TreeNode right) {
super();
this.data = data;
this.left = left;
this.right = right;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public TreeNode getLeft() {
return left;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public TreeNode getRight() {
return right;
}
public void setRight(TreeNode right) {
this.right = right;
}
}
/**\
* 初始化一个二叉树
* @return
*/
public TreeNode init() {
TreeNode treeNode3 = new TreeNode(3, null, null);
TreeNode treeNode4 = new TreeNode(4, null, null);
TreeNode treeNode6 = new TreeNode(6, null, null);
TreeNode treeNode2 = new TreeNode(2, treeNode3, treeNode4);
TreeNode treeNode5 = new TreeNode(5, null, treeNode6);
TreeNode treeNodeRoot = new TreeNode(1, treeNode2, treeNode5);
return treeNodeRoot;
}
public void printData(TreeNode treeNode) {
System.out.println("current node data: "+treeNode.getData());
}
/*
* 先序遍历:先跟节点,然后左右节点
*/
public void DLR(TreeNode treeNode) {
printData(treeNode);
if (treeNode.getLeft() != null) {
DLR(treeNode.getLeft());
}
if (treeNode.getRight()!= null) {
DLR(treeNode.getRight());
}
}
/*
* 中序遍历/中根遍历:先跟节点,然后左右节点
*/
public void LDR(TreeNode treeNode) {
if (treeNode.getLeft() != null) {
LDR(treeNode.getLeft());
}
printData(treeNode);
if (treeNode.getRight()!= null) {
LDR(treeNode.getRight());
}
}
/*
* 后序遍历:先跟节点,然后左右节点
*/
public void LRD(TreeNode treeNode) {
if (treeNode.getLeft() != null) {
LRD(treeNode.getLeft());
}
if (treeNode.getRight()!= null) {
LRD(treeNode.getRight());
}
printData(treeNode);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
BinaryTree2 binaryTree=new BinaryTree2();
TreeNode node=binaryTree.init();
System.out.println("DLR:");
binaryTree.DLR(node);
System.out.println("LDR");
binaryTree.LDR(node);
System.out.println("LRD");
binaryTree.LRD(node);
}
}
2.求二叉树的深度、广度(java)
(1)求二叉树的深度
//节点数据结构
class TreeNode {
TreeNode left = null;
TreeNode right = null;
}
//最大深度,基本思路是:使用递归,分别求出左子树的深度、右子树的深度,两个深度的较大值+1就是最大深度。
// 获取最大深度
public static int getMaxDepth(TreeNode treeNode) {
if (treeNode == null)
return 0;
else {
int left = getMaxDepth(treeNode.left);
int right = getMaxDepth(treeNode.right);
return 1 + Math.max(left, right);
}
}
// 获取最小深度
public static int getMinDepth(TreeNode treeNode) {
if (treeNode == null)
return 0;
else {
int left = getMinDepth(treeNode.left);
int right = getMinDepth(treeNode.right);
return 1 + Math.min(left, right);
}
}
(2)最大宽度,基本思路:使用队列,按层次遍历二叉树。在上一层遍历完成后,下一层的所有节点已经放到队列中,此时队列中的元素个数就是下一层的宽度。以此类推,依次遍历下一层即可求出二叉树的最大宽度。
// 获取最大宽度
public static int getMaxWidth(TreeNode treeNode) {
if (treeNode == null)
return 0;
Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
int maxWitdth = 1; // 最大宽度
queue.add(treeNode); // 入队
while (true) {
int len = queue.size(); // 当前层的节点个数
if (len == 0)
break;
while (len > 0) {// 如果当前层,还有节点
TreeNode node = queue.poll();
len--;
if (node.left != null)
queue.add(node.left); // 下一层节点入队
if (node.right != null)
queue.add(node.right);// 下一层节点入队
}
maxWitdth = Math.max(maxWitdth, queue.size());
}
return maxWitdth;
}
3.广度优先遍历二叉树
广度优先周游二叉树(层序遍历)是用队列来实现的,从二叉树的第一层(根结点)开始,自上至下逐层遍历;在同一层中,按照从左到右的顺序对结点逐一访问。
按照从根结点至叶结点、从左子树至右子树的次序访问二叉树的结点。算法:
1初始化一个队列,并把根结点入列队;
2当队列为非空时,循环执行步骤3到步骤5,否则执行6;
3出队列取得一个结点,访问该结点;
4若该结点的左子树为非空,则将该结点的左子树入队列;
5若该结点的右子树为非空,则将该结点的右子树入队列;
6结束。
4.非递归深度优先遍历二叉树
栈是实现递归的最常用的结构,利用一个栈来记下尚待遍历的结点或子树,以备以后访问,可以将递归的深度优先遍历改为非递归的算法。
- 非递归前序遍历:遇到一个结点,就访问该结点,并把此结点推入栈中,然后下降去遍历它的左子树。遍历完它的左子树后,从栈顶托出这个结点,并按照它的右链接指示的地址再去遍历该结点的右子树结构。
- 非递归中序遍历:遇到一个结点,就把它推入栈中,并去遍历它的左子树。遍历完左子树后,从栈顶托出这个结点并访问之,然后按照它的右链接指示的地址再去遍历该结点的右子树。
- 非递归后序遍历:遇到一个结点,把它推入栈中,遍历它的左子树。遍历结束后,还不能马上访问处于栈顶的该结点,而是要再按照它的右链接结构指示的地址去遍历该结点的右子树。遍历遍右子树后才能从栈顶托出该结点并访问之。另外,需要给栈中的每个元素加上一个特征位,以便当从栈顶托出一个结点时区别是从栈顶元素左边回来的(则要继续遍历右子树),还是从右边回来的(该结点的左、右子树均已周游)。特征为Left表示已进入该结点的左子树,将从左边回来;特征为Right表示已进入该结点的右子树,将从右边回来。
- 简洁的非递归前序遍历:遇到一个结点,就访问该结点,并把此结点的非空右结点推入栈中,然后下降去遍历它的左子树。遍历完左子树后,从栈顶托出一个结点,并按照它的右链接指示的地址再去遍历该结点的右子树结构。