后序非递归:首先要找到的是最左下的节点,然后根据后序遍历 左-右-根的顺序进行遍历,即找到之后判断是否有右子树,该右子树是否被访问过,若没有,可以入栈,访问其右子树,再访问右子树的左子树;若访问过,则可以访问当前的节点,并且记录访问的节点,并将访问过的指针置为零(未免将其重新压入栈中再次访问)
def PreOrder(root p):
r = p
t = NULL
stack s;
while(r or s):
while r:
s.push(r)
r = r.left
if !r:
r = s.top()
if (r.right and r.right != t):
r = r.right
s.push(r)
r = r.left
else:
r = s.pop()
print p
t = p
p = NULL
注意后序非递归的一个特性就是,此时仍在栈中的节点是当前访问节点的祖先节点!
中序非递归:
def InOrder(root p):
r = p
t = NULL
stack s;
while(r or s):
if r:
s.push(r)
r= r.lchild
else:
r = s.pop()
print r
r = r.rchild
中序非递归的一个重要用途就是搜索二叉树,是按顺序访问的
二叉树的深度:(非递归算法)
def depth(root p):
Q = []
front = -1
rear = -1
last= 0
level = 0
queue[rear] = T
rear += 1
while front < rear:
front += 1
p = Q[front]
if r.lchild:
rear += 1
Q[rear] = p.lchild
if r.rchile:
rear += 1
Q[reat] = p.rchild
if front == last:
level += 1
last = rear
return level
last指针指向下一层的末尾,每一次当front到达last时,就说明又遍历完了一层,last可以指向下一个末尾,这个也可以用来计算二叉树的宽度
平衡二叉树的判断:
def isBalance(root r, depth):
if r == NULL:
depth = 0
return True
else:
if isBalance(r.lchild, left) and isBalance(r.rchild, right):
diff = left - right
if abs(diff) <= 1:
depth = 1+ (left > right?left : right)
return True
return False
利用递归记录下来了每一个节点的深度并在下一层加以调用。
求一个树是不是另一个的子结构
这个完全是牛客大神的代码,注释很仔细,现在遇到树就会想想能不能递归一下,毕竟树就是一个递归建立的结构,很适合用递归反过来求一些东西~
链接:https://www.nowcoder.com/questionTerminal/6e196c44c7004d15b1610b9afca8bd88
来源:牛客网
public class Solution {
public static boolean HasSubtree(TreeNode root1, TreeNode root2) {
boolean result = false;
//当Tree1和Tree2都不为零的时候,才进行比较。否则直接返回false
if (root2 != null && root1 != null) {
//如果找到了对应Tree2的根节点的点
if(root1.val == root2.val){
//以这个根节点为为起点判断是否包含Tree2
result = doesTree1HaveTree2(root1,root2);
}
//如果找不到,那么就再去root的左儿子当作起点,去判断时候包含Tree2
if (!result) {
result = HasSubtree(root1.left,root2);
}
//如果还找不到,那么就再去root的右儿子当作起点,去判断时候包含Tree2
if (!result) {
result = HasSubtree(root1.right,root2);
}
}
//返回结果
return result;
}
public static boolean doesTree1HaveTree2(TreeNode node1, TreeNode node2) {
//如果Tree2已经遍历完了都能对应的上,返回true
if (node2 == null) {
return true;
}
//如果Tree2还没有遍历完,Tree1却遍历完了。返回false
if (node1 == null) {
return false;
}
//如果其中有一个点没有对应上,返回false
if (node1.val != node2.val) {
return false;
}
//如果根节点对应的上,那么就分别去子节点里面匹配
return doesTree1HaveTree2(node1.left,node2.left) && doesTree1HaveTree2(node1.right,node2.right);
}