1.树的定义及存储方式
1.1树的定义
public class TreeNode<T>{
private int index;
private T data;
private TreeNode leftChild;
private TreeNode rightChild;
}
1.2存储方式
因为二叉树的运用较多,所以只以二叉树为例
class TreeNode{
int data;
TreeNode leftChild;
TreeNode rightChild;
}
2.二叉树的遍历
2.1递归实现二叉树遍历
public void preOrder(TreeNode root){
if(root == null){
return;
} else{
System.out.println("preOrder data:"+root.data);
preOrder(root.leftChild);
preOrder(root.rightChild);
}
}
public void midOrder(TreeNode root){
if(root == null){
return;
} else{
midOrder(root.leftChild);
System.out.println("midOrder data:"+root.data);
midOrder(root.rightChild);
}
}
public void postOrder(TreeNode root){
if(root == null){
return;
} else{
postOrder(root.leftChild);
postOrder(root.rightChild);
System.out.println("postOrder data:"+root.data);
}
}
2.2非递归实现二叉树遍历
非递归前序遍历
每访问一个结点后,在向左子树遍历下去之前,利用栈来记录该结点的右子女(如果有的话),以便在左子树退回时可以直接从栈顶取得右子树的根结点,继续其右子树的遍历。上图是过程的演示,先将null压入栈中,当栈中无元素时将其推出,表示结束。
public void preOrderNonRecursive(TreeNode root){
Stack<TreeNode> stack = new Stack<>();
stack.push(null);
while(root != null){
System.out.println("preOrderNonRecursive data:"+root.data);
if(root.rightChild != null){
stack.push(root.rightChild);
}
if(root.leftChild != null){
root = root.leftChild;
} else{
root = stack.pop();
}
}
}
非递归中序遍历
从根结点开始沿着leftChild到最下角的结点,将指针依次压入栈中,直到该结点的leftChild指针为NULL。访问它的数据后,再遍历该结点的右子树。此时该结点为栈中推出的指针。
public void midOrderNonRecursive(TreeNode root){
Stack<TreeNode> stack = new Stack<>();
do{
while(root != null){
stack.push(root.leftChild);
root = root.leftChild;
}
if(!stack.empty()){
root = stack.pop();
System.out.println("preOrderNonRecursive data:"+root.data);
root = root.rightChild;
}
} while(root != null || !stack.empty());
}
非递归后序遍历
因为后序遍历的访问顺序为左右根,所以在访问的时候比较麻烦,需要考虑到访问完左结点后,当前结点有无右结点需要访问,若有则需要右进访问右子树,所以要有一个变量来记录当前结点。
- 从根结点开始沿着leftChild到最下角的结点,将指针依次压入栈中,直到该结点的leftChild指针为NULL。
- 判断当前结点有无右子树,若有,则优先访问右子树
- 无右子树货已经访问过右子树则访问当前结点
public void postOrderNonRecursive(TreeNode root) {
Stack<TreeNode> nodeStack = new Stack<>();
TreeNode prev = root;
do {
while (root != null) {
nodeStack.push(root);
root = root.leftChild;
}
if (!nodeStack.empty()) {
TreeNode temp = nodeStack.peek().rightChild;
if (temp == null || temp == prev) {
root = nodeStack.pop();
System.out.println("postOrderNonRecursive data:" + root.getData());
prev = root;
root = null;
} else {
root = temp;
}
}
} while (root != null || !nodeStack.empty());
}