题目与思路
题目:假设二叉树中所有结点值为单个字符且均不相同,采用二叉链存储结构存储。设计一个算法求二叉树b中指定值为x的结点的双亲节点p,提示:根节点的双亲节点为NULL,若在b中未找到值为x的结点,p也为NULL;并用相关数据进行测试。
思路:在创建二叉树时直接将各个节点的parent节点保存起来。
代码
直接上代码:
#include <iostream>
using namespace std;
//-------------------------
#define MaxSize 100
//-------------------------
int count=0;//用于PreOrder(BTNode bt)的遍历函数中
//-------------------------
typedef char ElemType;
typedef struct tnode{ //二叉树定义
//设置两个ElemType变量,一个用于存其自身的节点值,一个存双亲节点值
ElemType data,parent;
struct tnode *lchild,*rchild;
}BTNode;//-----------------------
void DestroyBTree(BTNode *&bt){ //销毁二叉树
if(bt!=NULL){
DestroyBTree(bt->lchild);
DestroyBTree(bt->rchild);
delete bt;
}
}//------------------------------
int BTHeight(BTNode *bt){ //求树高
int lchilddep,rchilddep;
if(bt==NULL) return 0;
else{
lchilddep=BTHeight(bt->lchild);
rchilddep=BTHeight(bt->rchild);
return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);
}
}//-------------------------------------
int NodeCount(BTNode *bt){ //计算节点数
int num1,num2;
if(bt==NULL)
return 0;
else{
num1=NodeCount(bt->lchild);
num2=NodeCount(bt->rchild);
return (num1+num2+1);
}
}//-----------------------------------------
int LeafCount(BTNode *bt){ //计算叶子数
int num1,num2;
if(bt==NULL)
return 0;
else if (bt->lchild==NULL&&bt->rchild==NULL)
return 1;
else{
num1=LeafCount(bt->lchild);
num2=LeafCount(bt->rchild);
return (num1+num2);
}
}//-------------------------------------------
void DispBTree(BTNode *bt){ //输出二叉树
if (bt!=NULL){
cout<<bt->data;
if (bt->lchild!=NULL || bt->rchild!=NULL){
cout<<"(";
DispBTree(bt->lchild);
if (bt->rchild!=NULL)
cout<<",";
DispBTree(bt->rchild);
cout<<")";
}
}
}//-----------------------------------------
void CreateBTree(BTNode * &bt,char *str) //由括号表示串创建二叉链
{ BTNode *St[MaxSize],*p=NULL;
int top=-1,k,j=0;
char ch;
bt=NULL; //建立的二叉树初始时为空
ch=str[j];
while (ch!='\0') //str未扫描完时循环
{ switch(ch)
{
case '(':top++;St[top]=p;k=1;
break; //为左孩子结点
case ')':top--;break;
case ',':k=2; break; //为右孩子结点
default:p=new BTNode();
p->data=ch;p->lchild=p->rchild=NULL;
if (bt==NULL){ //*p为二叉树的根结点
p->parent='#'; //根节点无双亲节点 ,特殊标注
bt=p;}
else //已建立二叉树根结点
{
switch(k)
{
//若为左孩子,双亲节点必在从该节点往前数第二个的位置 ,例:A(B,C)
case 1:p->parent=str[j-2];St[top]->lchild=p;break;
case 2:
//若为右孩子
//无左孩子
if(str[j-2]=='(')
p->parent=str[j-3];
//有左孩子,但左孩子为叶子节点
else if(str[j-3]=='(')
p->parent=str[j-4];
//有左孩子,且左孩子不是叶子节点
//在完整子树中,左括号数必等于右括号数
else if(str[j-2]==')'){
int h=1,u=0,g=j-2;
while(g!=0){
if(h==u) break;
if(str[g-1]=='(')
u++;
else if(str[g-1]==')')
h++;
g--;
}
p->parent=str[g-3];
}
St[top]->rchild=p;break;
}
}
}
j++;
ch=str[j];
}
}//-----------------------------------------------
void PreOrder(BTNode * bt,ElemType m){ //遍历二叉树
if(bt!=NULL){
//cout<<bt->data;
if(bt->data==m){
if(bt->parent=='#'){ //若为头节点
cout<<"NULL";
count++; //避免重复输出NULL
}
else {
cout<<bt->parent; //找到对应的节点
count++; //记录是否找到对应的节点
}
}
PreOrder(bt->lchild,m);
PreOrder(bt->rchild,m);
}
}
int main(){
char tree[MaxSize];
cin>>tree;
ElemType m;
cin>>m;
BTNode *bt;
CreateBTree(bt,tree);
PreOrder(bt,m);
if(count==0) //没有找到对应的节点,输出 "NULL"
cout<<"NULL";
DestroyBTree(bt);
return 0;
}