文档库 最新最全的文档下载
当前位置:文档库 › 2012年宁夏回族自治区数据概述摘要

2012年宁夏回族自治区数据概述摘要

1、二叉树的层次遍历序列的第一个结点是二叉树的根。实际上,层次遍历序列中的每个结点都是“局部根”。确定根后,到二叉树的中序序列中,查到该结点,该结点将二叉树分为“左根右”三部分。若左、右子树均有,则层次序列根结点的后面应是左右子树的根;若中序序列中只有左子树或只有右子树,则在层次序列的根结点后也只有左子树的根或右子树的根。这样,定义一个全局变量指针R,指向层次序列待处理元素。算法中先处理根结点,将根结点和左右子女的信息入队列。然后,在队列不空的条件下,循环处理二叉树的结点。队列中元素的数据结构定义如下:

typedef struct

{ int lvl; //层次序列指针,总是指向当前“根结点”在层次序列中的位置

int l,h; //中序序列的下上界

int f; //层次序列中当前“根结点”的双亲结点的指针

int lr; // 1—双亲的左子树 2—双亲的右子树

}qnode;

BiTree Creat(datatype in[],level[],int n)

//由二叉树的层次序列level[n]和中序序列in[n]生成二叉树。 n是二叉树的结点数

{if (n<1) {printf(“参数错误\n”); exit(0);}

qnode s,Q[]; //Q是元素为qnode类型的队列,容量足够大

init(Q); int R=0; //R是层次序列指针,指向当前待处理的结点

BiTree p=(BiTree)malloc(sizeof(BiNode)); //生成根结点

p->data=level[0]; p->lchild=null; p->rchild=null; //填写该结点数据

for (i=0; i

if (in[i]==level[0]) break;

if (i==0) //根结点无左子树,遍历序列的1—n-1是右子树

{p->lchild=null;

s.lvl=++R; s.l=i+1; s.h=n-1; s.f=p; s.lr=2; enqueue(Q,s);

}

else if (i==n-1) //根结点无右子树,遍历序列的1—n-1是左子树

{p->rchild=null;

s.lvl=++R; s.l=1; s.h=i-1; s.f=p; s.lr=1; enqueue(Q,s);

}

else //根结点有左子树和右子树

{s.lvl=++R; s.l=0; s.h=i-1; s.f=p; s.lr=1;enqueue(Q,s);//左子树有关信息入队列s.lvl=++R; s.l=i+1;s.h=n-1;s.f=p; s.lr=2;enqueue(Q,s);//右子树有关信息入队列

}

while (!empty(Q)) //当队列不空,进行循环,构造二叉树的左右子树

{ s=delqueue(Q); father=s.f;

for (i=s.l; i<=s.h; i++)

if (in[i]==level[s.lvl]) break;

p=(bitreptr)malloc(sizeof(binode)); //申请结点空间

p->data=level[s.lvl]; p->lchild=null; p->rchild=null; //填写该结点数据

if (s.lr==1) father->lchild=p;

else father->rchild=p; //让双亲的子女指针指向该结点

if (i==s.l)

{p->lchild=null; //处理无左子女

s.lvl=++R; s.l=i+1; s.f=p; s.lr=2; enqueue(Q,s);

}

else if (i==s.h)

{p->rchild=null; //处理无右子女

s.lvl=++R; s.h=i-1; s.f=p; s.lr=1; enqueue(Q,s);

}

else{s.lvl=++R; s.h=i-1; s.f=p; s.lr=1; enqueue(Q,s);//左子树有关信息入队列

s.lvl=++R; s.l=i+1; s.f=p; s.lr=2; enqueue(Q,s); //右子树有关信息入队列}

}//结束while (!empty(Q))

return(p);

}//算法结束

2、后序遍历最后访问根结点,即在递归算法中,根是压在栈底的。采用后序非递归算法,栈中存放二叉树结点的指针,当访问到某结点时,栈中所有元素均为该结点的祖先。本题要找p和q 的最近共同祖先结点r ,不失一般性,设p在q的左边。后序遍历必然先遍历到结点p,栈中元素均为p的祖先。将栈拷入另一辅助栈中。再继续遍历到结点q时,将栈中元素从栈顶开始逐个到辅助栈中去匹配,第一个匹配(即相等)的元素就是结点p 和q的最近公共祖先。

typedef struct

{BiTree t;int tag;//tag=0 表示结点的左子女已被访问,tag=1表示结点的右子女已被访问

}stack;

stack s[],s1[];//栈,容量够大

BiTree Ancestor(BiTree ROOT,p,q,r)//求二叉树上结点p和q的最近的共同祖先结点r。{top=0; bt=ROOT;

while(bt!=null ||top>0)

{while(bt!=null && bt!=p && bt!=q) //结点入栈

{s[++top].t=bt; s[top].tag=0; bt=bt->lchild;} //沿左分枝向下

if(bt==p) //不失一般性,假定p在q的左侧,遇结点p时,栈中元素均为p的祖先结点{for(i=1;i<=top;i++) s1[i]=s[i]; top1=top; }//将栈s的元素转入辅助栈s1 保存

if(bt==q) //找到q 结点。

for(i=top;i>0;i--)//;将栈中元素的树结点到s1去匹配

{pp=s[i].t;

for (j=top1;j>0;j--)

if(s1[j].t==pp) {printf(“p 和q的最近共同的祖先已找到”);return (pp);}

while(top!=0 && s[top].tag==1) top--; //退栈

if (top!=0){s[top].tag=1;bt=s[top].t->rchild;} //沿右分枝向下遍历

}//结束while(bt!=null ||top>0)

return(null);//q、p无公共祖先

}//结束Ancestor

3、在有向图G中,如果r到G中的每个结点都有路径可达,则称结点r为G的根结点。编写一个算法完成下列功能:

(1).建立有向图G的邻接表存储结构;

(2).判断有向图G是否有根,若有,则打印出所有根结点的值。

4、给出折半查找的递归算法,并给出算法时间复杂度性分析。

相关文档