思路:用棧的非遞歸后根遍歷二叉樹時,遇到結點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;
}