说明:N代表当前节点,P代表父节点,L代表左孩子,R代表右孩子。空节点为nil(或者说null)。下面的1,2,3,4都是在前面的基础上的,2是在1不存在的基础上,3是在1和2都不存在的基础上,以此类推。
前序遍历
找前驱
1.是父节点的左孩子,前驱是父节点。如图1
2.是父节点右孩子,且父节点没有左孩子,前驱是父节点。如图3
3.是父节点右孩子,且父节点有左孩子,前驱父节点按照前序遍历完的最后一个节点。如图2
4.以上都找不到,前驱是nil
找后继
1.有左孩子,则后继为左孩子,如图4
2.无左孩子,有右孩子,则后继为右孩子,如图5
3.无孩子节点,则需要根据以下条件搜索,知道找到为止.如图6,虚线代表下面可能有子树。如图6
while(n->p != nil && (n->p->rChild == nil || n->p->rChild == n)){
n = n->p
}
if(n->p == nil){
next = nil
}else{
next = n->p->rChild//如果图中的红点不存在,也可能为空
}
4.以上都找不到,则为nil
思维导图:
中序遍历
找前驱
1.有左孩子,则前驱为最右的节点。如图7
2.父节点的右孩子,则前驱为父节点.如图8
3.父节点的左孩子,递归向上找,直到父节点的左孩子不是自己。如图9
while(n->p != nil && n->p->lChild == n){
n = n->p
}
if(n->p == nil){
pre = nil
}else{
pre = n->p
}
4.以上都找不到,则为nil
找后继
1.有右孩子,后继是右孩子。如图10
2.父节点的左孩子,后继是父节点。如图11。
3.父节点的右孩子,向上找,直到父节点的右孩子不是本身。如图12
while(n->p != nil && n->p->rChild == n){
n = n->p
}
if(n->p == nil){
next = nil
}else{
next = n->p
}
4.以上都找不到,则为nil
思维导图
后序遍历
找前驱
1.有右孩子节点,前驱为右孩子
2.有左孩子,无右孩子,前驱为左孩子
3.无左右孩子,是父节点的左孩子,向上找,直到父孩子的左孩子不为空,并且父孩子的右孩子是本身,则前驱是左孩子
4.无左右孩子,是父节点的右孩子,父节点有左孩子,则前驱是父节点的左孩子。
5.无左右孩子,是父节点的右孩子,父节点无左孩子,向上找,直到父孩子的左孩子不为空,前驱是父节点的左孩子(和3一样)
6.以上都找不到,为nil
找后继
1.是父节点的左孩子,父节点有右孩子,则是父节点右子树遍历的第一个节点
2.父节点的左孩子,父节点无右孩子,则是父节点
3.父节点的右孩子,则是父节点