之前总结的二叉树算法不外乎两种1)基于遍历的,2)基于一般递归的(当前树上的解和左右子树上解的关系)。第一种一般没有返回值,第二种一般是有返回值的。
这两种算法框架的参数列表里都只有一棵树,算法只能访问当前节点的左右子树,只能判断同一父节点的节点之间的关系。但有些问题不只同一父节点的节点(左右子树)之间的问题,可能是不同父节点的节点之间的问题,以上的算法就无能为力了。这时候要打破框框,在算法里引入多个树根,这样就可以处理不同父节点的节点之间的问题。
具体的,
1)二叉树同层次结点加链接问题:
void connect(Node *root, Node *sibling)
{
if(!root) return;
root->next= sibling;
connect(root->left,root->right);
if(sibling)
connect(root->right, sibling->left);
else
connect(root->right, NULL);
}
2)判断是否是二叉排序树问题:
条件:a, 当前结点值大于它的左子树中所有节点值,b. 当前节点大于等于它的右子树所有节点值。直观的算法,参数上只有root就可以,没有其他信息,需要在算法体内部判断当前节点和它左子树节点的及右子树节点的关系,左子树节点和右子树节点都不是一个单个节点,而是一个集合,算法势必有循环进行多次比较。这样的递归算法就比较复杂。
换一个思路,不是直接按照定义用当前节点往下跟左右子树比,而是跟上边比——父节点的取值,确定了当前节点的取值范围,只要当前节点在这个范围内,就说明当前节点是满足条件的,再递归判断左右孩子节点。
bool isBST(Node* root, int leftBound, int rightBond)
{
if(!root) return true;
if(root->data>=leftBound && root->data<rightBond)
{
return isBST(root->left, leftBound, root->data) && isBST(root->right, root->data,rightBond);
}
return false;
}
3)判断一棵树是否是对称的
分析:仅在第一层是同一个节点的左右子树的判断问题,其他层都是不同父节点的的节点之间的判断问题,参数只有一个root是不行的。
bool isSymetric(Node* a, Node*b)
{
if(!a&&!b) return true;
else if(!a||!b) return false;
if(a->data!=b->data)
return false;
return(isSymetric(a->left,b->right) && isSymetric(a->right,b->left));
}
bool isSymetirc(Node *root)
{
if(!root) return true;
return isSymetric(root->left, root->right);
}