- 以往方法都是,按照父子右关系处理,具体思路如下:
中序遍历:左 -> 根 -> 右
分三种情况:
1.如果当前节点为空,直接返回空;
2.如果当前节点有右子树,则返回右子树的最左子树;
3.如果当前节点没有右子树,再分两种情况:
3-1看看当前节点是不是它的父节点的左子树,如果是,则返回它的父节点;
3-2如果当前节点不是它的父节点的左子树,则把父节点赋给当前节点,
再判断当前节点是不是它的父节点的左子树,直到当前节点是不是它的父节点的左子树,返回它的父节点
- 其次,还有以目标节点为问题中心的,区分 目标节点是否为叶子
1. 叶子节点,左叶子,下一节点就是父节点,右叶子,则把其父亲赋给当前节点,判断当前节点是否父节点的右孩子
若是则输出该父节点,若不是,则把其父亲赋给当前节点,再由当前节点遍历到最左边,输出
2.非叶子情况,意味着当前节点处于中序遍历的根部;有右孩子,直接返回,右孩子下面不为空,返回其最左
没有右孩子,判断当前节点是否父节点的左孩子····
- 递归的本质就是,循环处理,大问题化相同小问题,思路简单,代码实现很容易
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
// root 二叉树根节点,elem 待查找的元素,last二叉树最后一个节点;函数返回待查询元素的下一个节点
// last = root+sizeof(二叉树)/sizeof(Node) 根节点指针移动到二叉树尾部
Node* search(Node* root,int elem,int* last)
{
if(root->data==elem) //目标节点是根节点
{
if(root->right!=NULL) //非叶子
{
cout<<"Find!"<<"\t";
return root->right;
}
else
{
cout<<"Find!"<<"\t";
return NULL; //树只有一个节点或者是叶子情况
}
}
if(root->data!=elem&&root->left!=NULL)
{
root->left=search(root->left,elem,last); // 可能左子树空了,即左叶子,root要回到父节点
}
if(root->data!=elem&&root->right!=NULL)
{
root->right=search(root->right,elem,last);
}
// 用左右子树是否为空 控制遍历到最后,有逻辑问题;用长度控制,得多传几个参数,求步长;用节点控制较合适
if(root->data!=elem&&root->data==*last) //有且仅有一个节点,且该节点不是目标值;或者没找到目标。遍历到最后,涵盖叶子情况
{
cout<<"No find!";
return NULL;
}
}