记录数据结构pta作业,多有不足
题目
已知树结点为互不相等且不等于0的整数。请编写程序找出非空树中两个结点的最近公共祖先。例如对于图1(a)所示的树t,结点1和2的最近公共祖先是5;结点2和4的最近公共祖先是8。
输入格式:
每个测试点包含多组数据,第1行为一个正整数T,表示数组组数。每组数据为2行,第1行为一组用空格间隔的整数,个数不超过100个,表示带空指针信息的二叉树先根序列。其中空指针信息用0表示。第2行为空格间隔的两个互不相等的整数A和B,表示给定的两个结点值,保证A和B肯定在输入的树中。
注:我们已知二叉树与其自然对应的树相比,二叉树中结点的左孩子对应树中结点的左孩子,二叉树中结点的右孩子对应树中结点的右兄弟。进而我们可以利用“带空指针信息的先根序列构建二叉树”的方法来构建其对应的树的左孩子-右兄弟存储结构。如8 5 1 0 6 0 2 0 0 3 4 0 0 7 0 0 0对应图1(a)所示的树,1 2 0 3 0 4 0 0 0对应如图1(b)所示的树。
输出格式:
对每组数据输出一行,为一个整数,表示A和B的最近公共祖先结点的值。
输入样例1:
2
8 5 1 0 6 0 2 0 0 3 4 0 0 7 0 0 0
1 2
8 5 1 0 6 0 2 0 0 3 4 0 0 7 0 0 0
2 4
输出样例1:
5
8
思路
- 结点构造包括左右孩子以及parent,用于孩子兄弟表示法(二叉树)
- 孩子兄弟表示法和二叉树类似,不过把rchild变成brother了
- 采取递归方式构造该树
- 根据孩子兄弟表示法,构造正常的树,由于孩子可能不止两个,我用队列存储每个孩子
- 一个结点下,child是其第一个孩子,child的brother是下一个孩子,直到brother为NULL
- 类似层次遍历,我采用队列,在第五步时,压入栈
- 最后找到指定数据所在位置,向上寻找,嵌套循环,输出最近parent
代码
#include<iostream>
#include<queue>
using namespace std;
typedef struct TNode{
int data;
struct TNode *child,*brother,*parent;
}TNode,*pNode;
typedef struct TNode2{
int data;
struct TNode2* parent;
queue <TNode2*> child;
}TNode2,*pNode2;
pNode2 findIn(pNode2 root2,int num){
//cout<<"find"<<endl;
if(root2==NULL){
return 0;
}
else{
pNode2 p = root2;
queue <pNode2> q;
q.push(p);
//cout<<"push"<<p->data<<endl;
while(!q.empty()){
pNode2 temp = q.front();
q.pop();
//cout<<"pop"<<temp->data<<endl;
if(temp->data==num){
return temp;
}
else{
int n = temp->child.size();
for(int i = 0; i < n; i++){
pNode2 node = new TNode2;
node->data = temp->child.front()->data;
node->parent = temp->child.front()->parent;
node->child = temp->child.front()->child;
temp->child.push(node);
q.push(node);
//cout<<"push"<<node->data<<endl;
temp->child.pop();
}
}
}
}
}
void creatbroTree(pNode &node){
int num;
pNode p = node;
cin >> num;
if(num==0){
return;
}
else{
node = new TNode;
node->data = num;
node->brother = NULL;
node->child = NULL;
creatbroTree(node->child);
creatbroTree(node->brother);
}
}
pNode2 creatbiTree(pNode2 &root2,pNode &root1){
//cout<<"creat"<<endl;
if(root1==NULL){
return NULL;
}
else{
pNode2 par = root2;
pNode cur = root1;
queue <pNode2> q;
queue <pNode> q1;
pNode2 node = new TNode2;
pNode2 re = node;
node->data = root1->data;
node->parent = par;
par = node;
q.push(par);
//cout<<"push"<<par->data<<endl;
q1.push(cur);
while(!q.empty()){
pNode2 temp = q.front();
par = temp;
q.pop();
//cout<<"pop"<<temp->data<<endl;
cur = q1.front();
q1.pop();
pNode p = cur->child;
while(p!=NULL){
q1.push(p);
pNode2 node = new TNode2;
node->data = p->data;
node->parent = par;
par->child.push(node);
q.push(node);
//cout<<"push"<<node->data<<endl;
p = p->brother;
}
}
return re;
}
}
int main(){
int n;int a,b;
pNode pre=NULL;
pNode2 pa=NULL;
pNode2 pb=NULL;
cin>>n;
for(int i = 0; i < n; i++){
pNode root1 = NULL;
pNode2 root2 = NULL;
creatbroTree(root1);
root2 = creatbiTree(root2,root1);
cin>>a>>b;
pa = findIn(root2,a);
pb = findIn(root2,b);
pNode2 memory = pb;
while(pa!=NULL){
while(pb!=NULL){
if((pa->data)==(pb->data)){
cout<<pa->data<<endl;
break;
}
pb = pb->parent;
}
if(pa==pb){
break;
}
pa = pa->parent;
pb = memory;
}
}
system("pause");
return 0;
}