使用Java语言实现二叉树的生成
//arrs为放入到树节点的数据,demo中将int类型的数据置入节点中
public List<TreeNode> initTree(int[] arrs) {
List<TreeNode> nodes = new ArrayList<TreeNode>();
for (int data : arrs) {
nodes.add(new TreeNode(data));
}
//此处每个父节点的index < (arrs.length / 2 - 1)是确保每个父节点的左右子节点都存在
for (int parentIndex = 0; parentIndex < arrs.length / 2 - 1; parentIndex++) {
nodes.get(parentIndex).leftNode = nodes.get(parentIndex * 2 + 1);
nodes.get(parentIndex).rightNode = nodes.get(parentIndex * 2 + 2);
}
//(arrs.length / 2 - 1)最后一个父节点,通过二叉树的定义可知
int lastParentIndex = arrs.length / 2 - 1;
nodes.get(lastParentIndex).leftNode = nodes.get(lastParentIndex * 2 + 1);
//arrs.length % 2 != 0,作为判断最后一个父节点的右子节点是否存在的判断条件
if(arrs.length % 2 != 0){
nodes.get(lastParentIndex).rightNode = nodes.get(lastParentIndex * 2 + 2);
}
return nodes;
}
三种遍历方式
(1). 先序遍历
(2). 中序遍历
(3). 后序遍历
三种遍历方式,也就是遍历的顺序不一样。
先序遍历: “根左右”,遍历的顺序: 根节点->左节点->右节点。
中序遍历: “左根右”,遍历的顺序: 左节点->根节点->右节点。
后序遍历: “左右根”,遍历的顺序: 左节点->右节点->根节点。
先序遍历
使用递归
/*
* 先序遍历二叉树: 根左右
*
* @param node
* 遍历的节点
* */
public void preOrderTraverse(TreeNode node){
if(node == null)
return;
System.out.print(node.data + " "); //第一次进来是rootNode
preOrderTraverse(node.leftNode); //递归输出左节点
preOrderTraverse(node.rightNode); //递归输出右节点
}
使用循环
/*
* 先序遍历二叉树: 根左右
*
* 使用循环
*
* @param node
* 遍历的节点
* */
public void preOrderTraverseByWhile(TreeNode node){
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(node);
TreeNode currentNode;
while (!stack.isEmpty()) {
currentNode = stack.pop();
System.out.print(currentNode.data + " ");
if(currentNode.rightNode != null){
stack.push(currentNode.rightNode);
}
if (currentNode.leftNode != null) {
stack.push(currentNode.leftNode);
}
}
}
中序遍历
使用递归
/*
* 中序遍历二叉树: 左根右
*
* @param node
* 遍历的节点
* */
public void inOrderTraverse(TreeNode node){
if(node == null)
return;
inOrderTraverse(node.leftNode); //递归输出左节点
System.out.print(node.data + " ");
inOrderTraverse(node.rightNode); //递归输出右节点
}
使用循环
/*
* 中序遍历二叉树: 左根右
*
* 使用循环
*
* @param node
* 遍历的节点
* */
public void inOrderTraverseByWhile(TreeNode node){
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode currentNode = node;
while (currentNode != null || !stack.isEmpty()) {
while(currentNode != null){
stack.push(currentNode);
currentNode = currentNode.leftNode;
}
if(!stack.isEmpty()){
currentNode = stack.pop();
System.out.print(currentNode.data + "");
currentNode = currentNode.rightNode;
}
}
}
后序遍历
使用递归
/*
* 后序遍历二叉树: 左右根
*
* @param node
* 遍历的节点
* */
public void afterOrderTraverse(TreeNode node){
if(node == null)
return;
afterOrderTraverse(node.leftNode);//递归输出左节点
afterOrderTraverse(node.rightNode);//递归输出右节点
System.out.print(node.data + " ");
}
使用循环
/*
* 后序遍历二叉树: 左右根
*
* 使用循环
*
* @param node
* 遍历的节点
* */
public void afterOrderTraverseByWhile(TreeNode node){
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode rightNode = null;
TreeNode currentNode = node;
while (currentNode != null || !stack.isEmpty()) {
while(currentNode != null){
stack.push(currentNode);
currentNode = currentNode.leftNode;
}
currentNode = stack.pop();
//当上一个访问的结点是右孩子或者当前结点没有右孩子则访问当前结点
while(currentNode != null && (currentNode.rightNode == null || currentNode.rightNode == rightNode)){
System.out.print(currentNode.data + " ");
rightNode = currentNode;
if(stack.isEmpty()){
return;
}
currentNode = stack.pop();
}
stack.push(currentNode);
currentNode = currentNode.rightNode;
}
}