求二叉树任意两个结点最近的共同祖先
2012-09-10 22:13
441 查看
思路:用栈的非递归后根遍历二叉树时,遇到结点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;
}
时间复杂度:和后根遍历一次二叉树一样,即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;
}
相关文章推荐
- 【题目23】找出二叉树上任意两个结点的最近共同父结点
- 019写程序在一棵二叉树中找到两个结点的最近共同祖先(keep it up)
- 微软面试题: 找出二叉树上任意两个结点的最近共同父结点。
- 微软面试题: 找出二叉树上任意两个结点的最近共同父结点。
- 求二叉树中任意两结点的最近共同祖先的算法及其证明
- 面试题: 找出二叉树上任意两个结点的最近共同父结点。
- 13、设计一个算法,找出二叉树上任意两个结点的最近共同父结点。
- 找出二叉树上任意两个结点的最近共同父结点。
- 微软面试题: 找出二叉树上任意两个结点的最近共同父结点。
- 利用栈,求以二叉链表表示的二叉树中的两个结点的最近共同祖先
- [算法 笔记] 查找二叉树上任意两个结点的最近共同祖先(更新版本)
- 查找二叉树某两个节点最近的共同祖先及改进方法
- 编号满二叉树 - 寻找任意两结点的最近共同祖先
- 二叉树 最近祖先lca + 两个结点的最小路径
- 二叉树中找两个结点的最近公共祖先结点
- 求一颗不含指向父节点指针的普通树中任意两个结点的最近公共祖先(O(N*N) 和 O(N) 算法)
- 求二叉树两结点最近的共同祖先结点
- 二叉树中找两个结点的最近的公共祖先结点
- 二叉树——查找两个任意节点的最近祖先
- 二叉树中找两个结点的最近的公共祖先结点