文档库 最新最全的文档下载
当前位置:文档库 › 2012山东省数据分析深入

2012山东省数据分析深入

1、请编写一个判别给定二叉树是否为二叉排序树的算法,设二叉树用llink-rlink法存储。

2、(1)p->rchild (2)p->lchild (3)p->lchild (4)ADDQ(Q,p->lchild) (5)ADDQ(Q,p->rchild)

25. (1)t->rchild!=null (2)t->rchild!=null (3)N0++ (4)count(t->lchild) (5)count(t->rchild)

26. .(1)top++ (2) stack[top]=p->rchild (3)top++ (4)stack[top]=p->lchild

27. (1)*ppos // 根结点(2)rpos=ipos (3)rpos–ipos (4)ipos (5)ppos+1

3、对二叉树的某层上的结点进行运算,采用队列结构按层次遍历最适宜。

int LeafKlevel(BiTree bt, int k) //求二叉树bt 的第k(k>1) 层上叶子结点个数

{if(bt==null || k<1) return(0);

BiTree p=bt,Q[]; //Q是队列,元素是二叉树结点指针,容量足够大

int front=0,rear=1,leaf=0; //front 和rear是队头和队尾指针, leaf是叶子结点数

int last=1,level=1; Q[1]=p; //last是二叉树同层最右结点的指针,level 是二叉树的层

while(front<=rear)

{p=Q[++front];

if(level==k && !p->lchild && !p->rchild) leaf++; //叶子结点

if(p->lchild) Q[++rear]=p->lchild; //左子女入队

if(p->rchild) Q[++rear]=p->rchild; //右子女入队

if(front==last) {level++; //二叉树同层最右结点已处理,层数增1

last=rear; } //last移到指向下层最右一元素

if(level>k) return (leaf); //层数大于k 后退出运行

}//while }//结束LeafKLevel

4、已知有向图G=(V,E),其中V={V1,V2,V3,V4,V5,V6,V7},

E={,,,,,,,,}

写出G的拓扑排序的结果。

G拓扑排序的结果是:V1、V2、V4、V3、V5、V6、V7

5、数组A和B的元素分别有序,欲将两数组合并到C数组,使C仍有序,应将A和B拷贝到

C,只要注意A和B数组指针的使用,以及正确处理一数组读完数据后将另一数组余下元素复

制到C中即可。

void union(int A[],B[],C[],m,n)

//整型数组A和B各有m和n个元素,前者递增有序,后者递减有序,本算法将A和B归并

为递增有序的数组C。

{i=0; j=n-1; k=0;// i,j,k分别是数组A,B和C的下标,因用C描述,下标从0开始

while(i=0)

if(a[i]

while(i

while(j>=0) c[k++]=b[j--];

}算法结束

4、要求二叉树按二叉链表形式存储。15分

(1)写一个建立二叉树的算法。(2)写一个判别给定的二叉树是否是完全二叉树的算法。BiTree Creat() //建立二叉树的二叉链表形式的存储结构

{ElemType x;BiTree bt;

scanf(“%d”,&x); //本题假定结点数据域为整型

if(x==0) bt=null;

else if(x>0)

{bt=(BiNode *)malloc(sizeof(BiNode));

bt->data=x; bt->lchild=creat(); bt->rchild=creat();

}

else error(“输入错误”);

return(bt);

}//结束 BiTree

int JudgeComplete(BiTree bt) //判断二叉树是否是完全二叉树,如是,返回1,否则,返回0

{int tag=0; BiTree p=bt, Q[]; // Q是队列,元素是二叉树结点指针,容量足够大

if(p==null) return (1);

QueueInit(Q); QueueIn(Q,p); //初始化队列,根结点指针入队

while (!QueueEmpty(Q))

{p=QueueOut(Q); //出队

if (p->lchild && !tag) QueueIn(Q,p->lchild); //左子女入队

else {if (p->lchild) return 0; //前边已有结点为空,本结点不空

else tag=1; //首次出现结点为空

if (p->rchild && !tag) QueueIn(Q,p->rchild); //右子女入队

else if (p->rchild) return 0; else tag=1;

} //while

return 1; } //JudgeComplete

6、本题应使用深度优先遍历,从主调函数进入dfs(v)时,开始记数,若退出dfs()前,已访问完有向图的全部顶点(设为n个),则有向图有根,v为根结点。将n个顶点从1到n编号,各调用一次dfs()过程,就可以求出全部的根结点。题中有向图的邻接表存储结构、记顶点个数的变量、以及访问标记数组等均设计为全局变量。建立有向图g的邻接表存储结构参见上面第2题,这里只给出判断有向图是否有根的算法。

int num=0, visited[]=0 //num记访问顶点个数,访问数组visited初始化。

const n=用户定义的顶点数;

AdjList g ; //用邻接表作存储结构的有向图g。

void dfs(v)

{visited [v]=1; num++; //访问的顶点数+1

if (num==n) {printf(“%d是有向图的根。\n”,v); num=0;}//if

p=g[v].firstarc;

while (p)

{if (visied[p->adjvex]==0) dfs (p->adjvex);

p=p->next;} //while

visited[v]=0; num--; //恢复顶点v

}//dfs

void JudgeRoot()

//判断有向图是否有根,有根则输出之。

{static int i ;

for (i=1;i<=n;i++ ) //从每个顶点出发,调用dfs()各一次。

{num=0; visited[1..n]=0; dfs(i); }

}// JudgeRoot

算法中打印根时,输出顶点在邻接表中的序号(下标),若要输出顶点信息,可使用g[i].vertex。

7、数组A和B的元素分别有序,欲将两数组合并到C数组,使C仍有序,应将A和B拷贝到C,只要注意A和B数组指针的使用,以及正确处理一数组读完数据后将另一数组余下元素复制到C中即可。

void union(int A[],B[],C[],m,n)

//整型数组A和B各有m和n个元素,前者递增有序,后者递减有序,本算法将A和B归并为递增有序的数组C。

{i=0; j=n-1; k=0;// i,j,k分别是数组A,B和C的下标,因用C描述,下标从0开始while(i=0)

if(a[i]

while(i

while(j>=0) c[k++]=b[j--];

}算法结束

4、要求二叉树按二叉链表形式存储。15分

(1)写一个建立二叉树的算法。(2)写一个判别给定的二叉树是否是完全二叉树的算法。BiTree Creat() //建立二叉树的二叉链表形式的存储结构

{ElemType x;BiTree bt;

scanf(“%d”,&x); //本题假定结点数据域为整型

if(x==0) bt=null;

else if(x>0)

{bt=(BiNode *)malloc(sizeof(BiNode));

bt->data=x; bt->lchild=creat(); bt->rchild=creat();

}

else error(“输入错误”);

return(bt);

}//结束 BiTree

int JudgeComplete(BiTree bt) //判断二叉树是否是完全二叉树,如是,返回1,否则,返回0

{int tag=0; BiTree p=bt, Q[]; // Q是队列,元素是二叉树结点指针,容量足够大

if(p==null) return (1);

QueueInit(Q); QueueIn(Q,p); //初始化队列,根结点指针入队

while (!QueueEmpty(Q))

{p=QueueOut(Q); //出队

if (p->lchild && !tag) QueueIn(Q,p->lchild); //左子女入队

else {if (p->lchild) return 0; //前边已有结点为空,本结点不空

else tag=1; //首次出现结点为空

if (p->rchild && !tag) QueueIn(Q,p->rchild); //右子女入队

else if (p->rchild) return 0; else tag=1;

} //while

return 1; } //JudgeComplete

8、两棵空二叉树或仅有根结点的二叉树相似;对非空二叉树,可判左右子树是否相似,采用递归算法。

int Similar(BiTree p,q) //判断二叉树p和q是否相似

{if(p==null && q==null) return (1);

else if(!p && q || p && !q) return (0);

else return(Similar(p->lchild,q->lchild) && Similar(p->rchild,q->rchild)) }//结束Similar

9、两棵空二叉树或仅有根结点的二叉树相似;对非空二叉树,可判左右子树是否相似,采用递归算法。

int Similar(BiTree p,q) //判断二叉树p和q是否相似

{if(p==null && q==null) return (1);

else if(!p && q || p && !q) return (0);

else return(Similar(p->lchild,q->lchild) && Similar(p->rchild,q->rchild)) }//结束Similar

10、4、 void LinkList_reverse(Linklist &L)

//链表的就地逆置;为简化算法,假设表长大于2

{

p=L->next;q=p->next;s=q->next;p->next=NULL;

while(s->next)

{

q->next=p;p=q;

q=s;s=s->next; //把L的元素逐个插入新表表头

}

q->next=p;s->next=q;L->next=s;

}//LinkList_reverse

11、给定n个村庄之间的交通图,若村庄i和j之间有道路,则将顶点i和j用边连接,边上的Wij表示这条道路的长度,现在要从这n个村庄中选择一个村庄建一所医院,问这所医院应建在哪个村庄,才能使离医院最远的村庄到医院的路程最短?试设计一个解答上述问题的算法,并应用该算法解答如图所示的实例。(20分)

12、题目中要求矩阵两行元素的平均值按递增顺序排序,由于每行元素个数相等,按平均值排列与按每行元素之和排列是一个意思。所以应先求出各行元素之和,放入一维数组中,然后选择一种排序方法,对该数组进行排序,注意在排序时若有元素移动,则与之相应的行中各元素也必须做相应变动。

void Translation(float *matrix,int n)

//本算法对n×n的矩阵matrix,通过行变换,使其各行元素的平均值按递增排列。

{int i,j,k,l;

float sum,min; //sum暂存各行元素之和

float *p, *pi, *pk;

for(i=0; i

{sum=0.0; pk=matrix+i*n; //pk指向矩阵各行第1个元素.

for (j=0; j

*(p+i)=sum; //将一行元素之和存入一维数组.

}//for i

for(i=0; i

{min=*(p+i); k=i; //初始设第i行元素之和最小.

for(j=i+1;j

if(i!=k) //若最小行不是当前行,要进行交换(行元素及行元素之和)

{pk=matrix+n*k; //pk指向第k行第1个元素.

pi=matrix+n*i; //pi指向第i行第1个元素.

for(j=0;j

{sum=*(pk+j); *(pk+j)=*(pi+j); *(pi+j)=sum;}

sum=p[i]; p[i]=p[k]; p[k]=sum; //交换一维数组中元素之和.

}//if

}//for i

free(p); //释放p数组.

}// Translation

[算法分析] 算法中使用选择法排序,比较次数较多,但数据交换(移动)较少.若用其它排序方法,虽可减少比较次数,但数据移动会增多.算法时间复杂度为O(n2).

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

14、设T是一棵满二叉树,编写一个将T的先序遍历序列转换为后序遍历序列的递归算法。

15、约瑟夫环问题(Josephus问题)是指编号为1、2、…,n的n(n>0)个人按顺时针方向围坐成一圈,现从第s个人开始按顺时针方向报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列,…,如此重复直到所有的人全部出列为止。现要求采用循环链表结构设计一个算法,模拟此过程。

相关文档
相关文档 最新文档