/**
* @author wkn
* @create 2021-12-03 9:55
*/
public class DepthFirstSearch {
public static void main(String ... args){
TreeNode root = new TreeNode(0);
root.leftNode = new TreeNode(1);
root.rightNode = new TreeNode(2);
root.leftNode.rightNode = new TreeNode(4);
List<Integer> preOrder = dfsPreOrder(root);
System.out.println("先序遍历");
show(preOrder);
System.out.println("\n******************");
System.out.println("中序遍历");
List<Integer> inOrder = dfsInOrder(root);
show(inOrder);
System.out.println("\n******************");
System.out.println("后序遍历");
List<Integer> lastOrder = dfsLastOrder(root);
show(lastOrder);
}
public static void show(List<Integer> list){
for(int val : list){
System.out.print(val+" ");
}
}
public static List<Integer> dfsPreOrder(TreeNode root){
if(root == null){
return null;
}
List<Integer> result = new ArrayList<Integer>();
Stack<TreeNode> treeNodes = new Stack<>();
treeNodes.add(root);
while(!treeNodes.isEmpty()){
TreeNode pop = treeNodes.pop();
result.add(pop.val);
//后进先出,所以左子结点先出来
if(pop.rightNode != null){
treeNodes.push(pop.rightNode);
}
if(pop.leftNode != null){
treeNodes.push(pop.leftNode);
}
}
return result;
}
public static List<Integer> dfsInOrder(TreeNode root){
if(root == null){
return null;
}
List<Integer> result = new ArrayList<Integer>();
Stack<TreeNode> treeNodes = new Stack<TreeNode>();
while(root != null || !treeNodes.isEmpty()){
while(root != null){
treeNodes.push(root);
root = root.leftNode;
}
root = treeNodes.pop();//每个结点自身又是中间的,又是父节点的子节点
result.add(root.val);
root = root.rightNode;//当前结点的右结点
}
return result;
}
public static List<Integer> dfsLastOrder(TreeNode root){
if(root == null){
return null;
}
List<Integer> result = new ArrayList<Integer>();
Stack<TreeNode> treeNodes = new Stack<TreeNode>();
TreeNode prev = null;
while(root != null || !treeNodes.isEmpty()){
while(root != null){
treeNodes.push(root);
root = root.leftNode;
}
root = treeNodes.pop();//第一次可能是最左结点,但是也是中间的结点
if(root.rightNode == null || root.rightNode == prev){ //当前结点没有右节点 或者 当前结点的右节点已经添加到序列中了
result.add(root.val);//可以将当前结点遍历进序列中
prev = root;
root = null;
}else{ //当前结点还有右节点,将当前结点入栈,先去遍历右子树
treeNodes.push(root);
root = root.rightNode;
}
}
return result;
}
}
class TreeNode{
int val;
TreeNode leftNode;
TreeNode rightNode;
public TreeNode(){}
public TreeNode(int val){
this.val = val;
}
public TreeNode(int val, TreeNode leftNode, TreeNode rightNode){
this.val = val;
this.leftNode = leftNode;
this.rightNode = rightNode;
}
}
迭代的前序遍历也可以这样写:
public static List<Integer> dfsPreOrder(TreeNode root){
if(root == null){
return null;
}
List<Integer> result = new ArrayList<Integer>();
Stack<TreeNode> treeNodes = new Stack<>();
/*while(!treeNodes.isEmpty()){
TreeNode pop = treeNodes.pop();
result.add(pop.val);
//后进先出,所以左子结点先出来
if(pop.rightNode != null){
treeNodes.push(pop.rightNode);
}
if(pop.leftNode != null){
treeNodes.push(pop.leftNode);
}
}*/
while(root != null || !treeNodes.isEmpty()){
while(root != null){
result.add(root.val);
treeNodes.push(root);
root = root.leftNode;
}
root = treeNodes.pop();
root = root.rightNode;
}
return result;
}