思路:用栈的非递归后根遍历二叉树时,遇到结点p时,栈中保存的即为p的所有祖先。利用这一点,在一次遍历中分布找出p和q的所有祖先,再找它们的共同祖先就容易了。
时间复杂度:和后根遍历一次二叉树一样,即O(n)。
空间复杂度:O(h),h为二叉树的高度。
数据结构:
struct BinTreeNode;
typedef struct BinTreeNode * PBinTreeNode;
struct BinTreeNode
{
char info;
PBinTreeNode llink;
PBinTreeNode rlink;
};
typedef struct BinTreeNode *BinTree;
typedef struct
{
PBinTreeNode ptr;
int tag;
}Elem;
struct SeqStack
{
Elem s[MAXNUM];
int t;
};
typedef struct SeqStack * PSeqStack;
程序代码:
PBinTreeNode ancestor(BinTree t,PBinTreeNode p,PBinTreeNode q)
{
Elem stnode;
PSeqStack st;
PBinTreeNode pbnode,pstring[MAXNUM],qstring[MAXNUM]; //分别用于存放p和q的祖先
char continueflag;
int i,findflag = 0;
if(t == NULL)
return NULL;
st = createEmptyStack();
pbnode = t;
do
{
while(pbnode != NULL)
{
stnode.ptr = pbnode;
stnode.tag = 1;
push(st,stnode);
pbnode = pbnode->llink;
}
while(!isEmptyStack(st))
{
stnode = pop(st);
pbnode = stnode.ptr;
if(stnode.tag == 1)
{
stnode.ptr = 2;
push(st,stnode);
pbnode = pbnode->rlink;
break;
}
else
{
if(pbnode == p)
{
for(i = 0;i < st->s[i];i++)
pstring[i] = st->s[i].ptr; //保存p的祖先
ptstring[i] =NULL;
findflag++; //找到一个祖先
}
if(pbnode == q)
{
for(i = 0;i < st->s[i];i++)
qstring[i] = st->s[i].ptr; //保存p的祖先
qtstring[i] =NULL;
findflag++; //找到一个祖先
}
if(findflag == 2)
{
i = 0;
while((pstring[i] == qstring[i]) && (pstring[i] != NULL))
i++;
if(pstring[i] == NULL)
{
free(st);
return pstring[i-1];
}
else
{
free(st);
return qstring[i-1];
}
}
}
}
}while(!isEmptyStack(st));
return NULL;
}