2022年上半年安徽省JAVA版本入门_第1页
2022年上半年安徽省JAVA版本入门_第2页
2022年上半年安徽省JAVA版本入门_第3页
2022年上半年安徽省JAVA版本入门_第4页
2022年上半年安徽省JAVA版本入门_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第第页2022年上半年安徽省JAVA版本入门2022年上半年安徽省JAVA最新版本入门

1、假设第n件物品能放入背包,那么问题变为能否再从n-1件物品中选出假设干件放入背包〔这时背包可放入物品的重量变为s-w[n]〕。假设第n件物品不能放入背包,那么考虑从n-1件物品选假设干件放入背包〔这时背包可放入物品仍为s〕。假设最终s=0,那么有一解;否那么,假设s0或虽然s0但物品数n1,那么无解。

〔1〕s-w[n],n-1//Knap(s-w[n],n-1)=true

〔2〕s,n-1//Knap←Knap(s,n-1)

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

typedefstruct

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

intl,h;//中序序列的下上界

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

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

}qnode;

BiTreeCreat(datatypein[],level[],intn)

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

{if(n1){printf(“参数错误\n”);e*it(0);}

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

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

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

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

for(i=0;in;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);

}

elseif(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=le

2022年上半年安徽省JAVA最新版本入门

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

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

elsefather-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);

}

elseif(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);

}//算法结束

3、假设第n件物品能放入背包,那么问题变为能否再从n-1件物品中选出假设干件放入背包〔这时背包可放入物品的重量变为s-w[n]〕。假设第n件物品不能放入背包,那么考虑从n-1件物品选假设干件放入背包〔这时背包可放入物品仍为s〕。假设最终s=0,那么有一解;否那么,假设s0或虽然s0但物品数n1,那么无解。

〔1〕s-w[n],n-1//Knap(s-w[n],n-1)=true

〔2〕s,n-1//Knap←Knap(s,n-1)

4、设一组有序的记录关键字序列为(13,18,24,35,47,50,62,83,90),查找方法用二分查找,要求计算出查找关键字62时的比较次数并计算出查找胜利时的平均查找长度。

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

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

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

〔2〕.判断有向图G是否有根,假设有,那么打印出全部根结点的值。

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

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

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

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

9、请设计一个算法,要求该算法把二叉树的叶子结点按从左到右的顺次连成一个单链表,表头指针为head。二叉树按二叉链表方式存储,链接时用叶子结点的右指针域来存放单链表指针。分析你的算法的时、空繁复度。

10、后序遍历最末访问根结点,即在递归算法中,根是压在栈底的。采纳后序非递归算法,栈中存放二叉树结点的指针,当访问到某结点时,栈中全部元素均为该结点的祖先。

此题要找p和q的最近共同祖先结点r,不失一般性,设p在q的左边。后序遍历必定先遍历到结点p,栈中元素均为p的祖先。将栈拷入另一帮助栈中。再继续遍历到结点q时,将栈中元素从栈顶开始逐个到帮助栈中去匹配,第一个匹配〔即相等〕的元素就是结点p和q的最近公共祖先。

typedefstr

2022年上半年安徽省JAVA最新版本入门

uct

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

}stack;

stacks[],s1[];//栈,容量够大

BiTreeAncestor(BiTreeROOT,p,q,r)//求二叉树上结点p和q的最近的共同祖先结点r。

{top=0;bt=ROOT;

while(bt!=null||top0)

{while(bt!=nullbt!=pbt!=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;i0;i--)//;将栈中元素的树结点到s1去匹配

{pp=s[i].t;

for(j=top1;j0;j--)

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

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

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

}//结束while(bt!=null||top0)

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

}//结束Ancestor

11、我们可用“破圈法”求解带权连通无向图的一棵最小代价生成树。所谓“破圈法”就是“任取一圈,去掉圈上权最大的边”,反复执行这一步骤,直到没有圈为止。请给出用“破圈法”求解给定的带权连通无向图的一棵最小代价生成树的具体算法,并用程序实现你所给出的算法。注:圈就是回路。

12、设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、B和C用链式存储结构表示。

typedefstructnode{intdata;structnode*ne*t;}lklist;

voidintersection(lklist*ha,lklist*hb,lklist*hc)

{

lklist*p,*q,*t;

for(p=ha,hc=0;p!=0;p=p-ne*t)

{for(q=hb;q!=0;q=q-ne*t)if(q-data==p-data)break;

if(q!=0){t=(lklist*)malloc(sizeof(lklist));t-data=p-data;t-ne*t=hc;hc=t;}

}

}

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

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

constn=用户定义的顶点数;

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

voiddfs(v)

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

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

p=g[v].firstar

c;

while(p)

{if(visied[p-adjve*]==0)dfs(p-adjve*);

p=p-ne*t;}//while

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

}//dfs

voidJudgeRoot(

2022年上半年安徽省JAVA最新版本入门

)

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

{staticinti;

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

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

}//JudgeRoot

算法中打印根时,输出顶点在邻接表中的序号〔下标〕,假设要输出顶点信息,可运用g[i].verte*。

14、假设K1,…,Kn是n个关键词,试解答:

试用二叉查找树的插入算法建立一棵二叉查找树,即当关键词的插入次序为K1,K2,…,Kn时,用算法建立一棵以LLINK/RLINK链接表示的二叉查找树。

15、设有一组初始记录关键字为(45,80,48,40,22,78),要求构造一棵二叉排序树并给出构造过程。

16、有一种简约的排序算法,叫做计数排序〔countsorting〕。这种排序算法对一个待排序的表(用数组表示)进行排序,并将排序结果存放到另一个新的表中。需要留意的是,表中全部待排序的关键码互不相同,计数排序算法针对表中的每个记录,扫描待排序的表一趟,统计表中有多少个记录的关键码比该记录的关键码小,假设针对某一个记录,统计出的计数值为c,那么,这个记录在新的有序表中的合适的存放位置即为c。

(1)(3分)给出适用于计数排序的数据表定义;

(2)(7分)运用Pascal或C语言编写实现计数排序的算法;

(3)(4分)对于有n个记录的表,关键码比较次数是多少?

(4)(3分)与简约选择排序相比较,这种方法是否更好?为什么?

17、假设以邻接矩阵作为图的存储结构,编写算法判别在给定的有向图中是否存在一个简约有向回路,假设存在,那么以顶点序列的方式输出该回路〔找到一条即可〕。〔注:图中不存在顶点到自己的弧〕

有向图判断回路要比无向图繁复。利用深度优先遍历,将顶点分成三类:未访问;已访问但其邻接点未访问完;已访问且其邻接点已访问完。下面用0,1,2表示这三种状态。前面已提到,假设dfs〔v〕结束前涌现顶点u到v的回边,那么图中必有包含顶点v和u的回路。对应程序中v的状态为1,而u是正访问的顶点,假设我们找出u的下一邻接点的状态为1,就可以输出回路了。

voidPrint(intv,intstart)//输出从顶点start开始的回路。

{for(i=1;i=n;i++)

if(g[v][i]!=0visited[i]==1)//假设存在边〔v,i〕,且顶点i的状态为1。

{printf(“%d”,v);

if(i==start)printf(“\n”);elsePrint(i,start);break;}//if

}//Print

voiddfs(intv)

{visited[v]=1;

for(j=1;j=n;j++)

if(g[v][j]!=0)//存在边(v,j)

if(visited[j]!=1){if(!visited[j])dfs(j);}//if

else{cycle=1;Print(j,j);

}

visited[v]=2;

}//dfs

voidfind_cycle()//判断是否有回路,有那么输出邻接矩阵。visited数组为全局变量。

{for(i=1;i=n;i++)visited[i]=0;

for(i=1;i=n;i++)if

2022年上半年安徽省JAVA最新版本入门

(!visited[i])dfs(i);

}//find_cycle

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

voidHospital(AdjMatri*w,intn)

//在以邻接带权矩阵表示的n个村庄中,求医院建在何处,使离医院最远的村庄到医院的路径最短。

{for(k=1;k=n;k++)//求任意两顶点间的最短路径

for(i=1;i=n;i++)

for(j=1;j=n;j++)

if(w[i][k]+w[k][j]w[i][j])w[i][j]=w[i][k]+w[k][j];

m=MA*INT;//设定m为机器内最大整数。

for(i=1;i=n;i++)//求最长路径中最短的一条。

{s=0;

for(j=1;j=n;j++)//求从某村庄i〔1=i=n〕到其它村庄的最长路径。

if(w[i][j]s)s=w[i][j];

if(s=m){m=s;k=i;}//在最长路径中,取最短的一条。m记最长路径,k记出发顶点的下标。

Printf(“医院应建在%d村庄,到医院距离为%d\n”,i,m);

}//for

}//算法结束

对以上实例模拟的过程略。各行中最大数依次是9,9,6,7,9,9。这几个最大数中最小者为6,故医院应建在第三个村庄中,离医院最远的村庄到医院的距离是6。

1、对图1所示的连通网G,请用Prim算法构造其最小生成树〔每选取一条边画一个图〕。

19、二部图〔bipartitegraph〕G=〔V,E〕是一个能将其结点集V分为两不相交子集V1和V2=V-V1的无向图,使得:V1中的任何两个结点在图G中均不相邻,V2中的任何结点在图G中也均不相邻。

〔1〕.请各举一个结点个数为5的二部图和非二部图的例子。

〔2〕.请用C或PASCAL编写一个函数BIPARTITE判断一个连通无向图G是否是二部图,并分析程序的时间繁复度。设G用二维数组A来表示,大小为n*n〔n为结点个数〕。请在程序中加须要的说明。假设有须要可径直利用堆栈或队列操作。【

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

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

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

21、二路插入排序是将待排关键字序列r[1..n]中关键字分二路分别按序插入到帮助向量d

[1..n]前半部和后半部〔注:向量d可视为循环表〕,其原那么为,先将r[l]赋给d[1],再从r[2]记录开始分二路插入。编写实现二路插入排序算法。

22、设指针变量p指向双向链表中结点A,指针变量q指向被插入结点B,要求给出在结点A的后面插入结点B的操作序列〔设双向链表中结点的两个

2022年上半年安徽省JAVA最新版本入门

指针域分别为llink和rlink〕。

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

typedefstruct

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

intl,h;//中序序列的下上界

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

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

}qnode;

BiTreeCreat(datatypein[],level[],intn)

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

{if(n1){printf(“参数错误\n”);e*it(0);}

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

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

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

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

for(i=0;in;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);

}

elseif(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;

elsefather-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);

}

elseif(i==s.h)

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

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

}

2022年上半年安徽省JAVA最新版本入门

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);

}//算法结束

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

intSimilar(BiTreep,q)//判断二叉树p和q是否相像

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

elseif(!pq||p!q)return(0);

elsereturn(Similar(p-lchild,q-lchild)Similar(p-rchild,q-rchild))

}//结束Similar

25、设一组有序的记录关键字序列为(13,18,24,35,47,50,62,83,90),查找方法用二分查找,要求计算出查找关键字62时的比较次数并计算出查找胜利时的平均查找长度。

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

27、设一棵二叉树的结点结构为(LLINK,INFO,RLINK),ROOT为指向该二叉树根结点的指针,p和q分别为指向该二叉树中任意两个结点的指针,试编写一算法ANCESTOR〔ROOT,p,q,r〕,该算法找到p和q的最近共同祖先结点r。

28、依据二叉排序树中序遍历所得结点值为增序的性质,在遍历中将当前遍历结点与其前驱结点值比较,即可得出结论,为此设全局指针变量pre〔初值为null〕和全局变量flag,初值为true。假设非二叉排序树,那么置flag为false。

#definetrue1

#definefalse0

typedefstructnode

{datatypedata;structnode*llink,*rlink;}*BTree;

voidJudgeBST〔BTreet,intflag〕

//判断二叉树是否是二叉排序树,本算法结束后,在调用程序中由flag得出结论。

{if〔t!=nullflag〕

{Judgebst〔t-llink,flag〕;//中序遍历左子树

if〔pre==null〕pre=t;//中序遍历的第一个结点不必判断

elseif〔pre-datat-data〕pre=t;//前驱指针指向当前结点

else{flag=flase;}//不是完全二叉树

Judgebst〔t-rlink,flag〕;//中序遍历右子树

}//JudgeBST算法结束

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

voidunion(intA[],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(imj=0)

if(a[i]b[j])c[k++]=a[i++]elsec

[k++]=b[j--];

while(im)c[k++]=a[i++];

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

}算法结束

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

〔1〕写一个建立二叉树的算法。〔2〕写一个判别给定的二叉树是否是完全二叉树的算

2022年上半年安徽省JAVA最新版本入门

法。

BiTreeCreat()//建立二叉树的二叉链表形式的存储结构

{ElemType*;BiTreebt;

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

if(*==0)bt=null;

elseif(*0)

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

bt-data=*;bt-lchild=creat();bt-rchild=creat();

}

elseerror(“输入错误”);

return(bt);

}//结束BiTree

intJudgeComplete(BiTreebt)//判断二叉树是否是完全二叉树,如是,返回1,否那么,返回0

{inttag=0;BiTreep=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)return0;//前边已有结点为空,本结点不空

elsetag=1;//首次涌现结点为空

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

elseif(p-rchild)return0;elsetag=1;

}//while

return1;}//JudgeComplete

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

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

〔2〕.判断有向图G是否有根,假设有,那么打印出全部根结点的值。

31、将顶点放在两个集合V1和V2。对每个顶点,检查其和邻接点是否在同一个集合中,如是,那么为非二部图。为此,用整数1和2表示两个集合。再用一队列结构存放图中访问的顶点。

intBPGraph(AdjMatri*g)

//判断以邻接矩阵表示的图g是否是二部图。

{ints[];//顶点向量,元素值表示其属于那个集合〔值1和2表示两个集合〕

intQ[];//Q为队列,元素为图的顶点,这里设顶点信息就是顶点编号。

intf=0,r,visited[];//f和r分别是队列的头尾指针,visited[]是访问数组

for(i=1;i=n;i++){visited[i]=0;s[i]=0;}//初始化,各顶点未确定属于那个集合

Q[1]=1;r=1;s[1]=1;//顶点1放入集合S1

while(fr)

{v=Q[++f];if(s[v]==1)jh=2;elsejh=1;//预备v的邻接点的集合号

if(!visited[v])

{visited[v]=1;//确保对每一个顶点,都要检查与其邻接点不应在一个集合中

for(j=1,j=n;j++)

if(g[v][j]==1){if(!s[j]){s[j]=jh;Q[++r]=j;}//邻接点入队列

elseif(s[j]==s[v])return(0);}//非二部图

}//if(!visited[v])

}//while

return(1)

;}//是二部图

[算法争论]题目给的是连通无向图,假设非连通,那么算法要修改。

32、设t是给定的一棵二叉树,下面的递归程序count(t)用于求得:二叉树t中具有非空的左,右两个儿子的结点个数N2;只有非空左儿子的个数NL;只有非空右儿子的结点个数NR和叶子结点个数N0。N2

2022年上半年安徽省JAVA最新版本入门

、NL、NR、N0都是全局量,且在调用count(t)之前都置为0.

typedefstructnode

{intdata;structnode*lchild,*rchild;}node;

intN2,NL,NR,N0;

voidcount(node*t)

{if(t-lchild!=NULL)if(1)___N2++;elseNL++;

elseif(2)___NR++;else(3)__;

if(t-lchild!=NULL)(4)____;if(t-rchild!=NULL)(5)____;

}

26.树的先序非递归算法。

voide*ample(b)

btree*b;

{btree*stack[20],*p;

inttop;

if(b!=null)

{top=1;stack[top]=b;

while(top0)

{p=stack[top];top--;

printf(“%d”,p-data);

if(p-rchild!=null)

{(1)___;(2)___;

}

if(p-lchild!=null)

(3)___;(4)__;

}}}}

33、4、voidLinkList_reverse(LinklistL)

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

{

p=L-ne*t;q=p-ne*t;s=q-ne*t;p-ne*t=NULL;

while(s-ne*t)

{

q-ne*t=p;p=q;

q=s;s=s-ne*t;//把L的元素逐个插入新表表头

}

q-ne*t=p;s-ne*t=q;L-ne*t=s;

}//LinkList_reverse

34、设t是给定的一棵二叉树,下面的递归程序count(t)用于求得:二叉树t中具有非空的左,右两个儿子的结点个数N2;只有非空左儿子的个数NL;只有非空右儿子的结点个数NR和叶子结点个数N0。N2、NL、NR、N0都是全局量,且在调用count(t)之前都置为0.

typedefstructnode

{intdata;structnode*lchild,*rchild;}node;

intN2,NL,NR,N0;

voidcount(node*t)

{if(t-lchild!=NULL)if(1)___N2++;elseNL++;

elseif(2)___NR++;else(3)__;

if(t-lchild!=NULL)(4)____;if(t-rchild!=NULL)(5)____;

}

26.树的先序非递归算法。

voide*ample(b)

btree*b;

{btree*stack[20],*p;

inttop;

if(b!=null)

{top=1;stack[top]=b;

while(top0)

{p=stack[top];top--;

printf(“%d”,p-data);

if(p-rchild!=null)

{(1)___;(2)___;

}

if(p-lchild!=null)

(3)___;(4)__;

}}}}

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

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

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

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

intSimilar(BiTreep,q)//判断二叉树p和q是否相像

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

elseif(!pq||p!q)return(0);

elsereturn(Similar(p-lchild,q-lchild)Similar(p-rchild,q-rchild))

}//结束Similar

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

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

intLeafKlevel(BiTreebt,intk)//求二叉树bt的第k(k1)层上叶子结点个数

{if(bt==null

||k1)return(0);

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

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

int

2022年上半年安徽省JAVA最新版本入门

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(levelk)return(leaf);//层数大于k后退出运行

}//while}//结束LeafKLevel

39、#definema*size栈空间容量

voidInOutS(ints[ma*size])

//s是元素为整数的栈,本算法进行入栈和退栈操作。

{inttop=0;//top为栈顶指针,定义top=0时为栈空。

for(i=1;i=n;i++)//n个整数序列作处理。

{scanf(“%d”,*);//从键盘读入整数序列。

if(*!=-1)//读入的整数不等于-1时入栈。

if(top==ma*size-1){printf(“栈满\n”);e*it(0);}

elses[++top]=*;//*入栈。

else//读入的整数等于-1时退栈。

{if(top==0){printf(“栈空\n”);e*it(0);}

elseprintf(“出栈元素是%d\n”,s[top--]);}

}

}//算法结

40、二路插入排序是将待排关键字序列r[1..n]中关键字分二路分别按序插入到帮助向量d[1..n]前半部和后半部〔注:向量d可视为循环表〕,其原那么为,先将r[l]赋给d[1],再从r[2]记录开始分二路插入。编写实现二路插入排序算法。

41、设一组有序的记录关键字序列为(13,18,24,35,47,50,62,83,90),查找方法用二分查找,要求计算出查找关键字62时的比较次数并计算出查找胜利时的平均查找长度。

42、假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,称可以操作的序列为合法序列,否那么称为非法序列。〔15分〕

〔1〕A和D是合法序列,B和C是非法序列。

〔2〕设被判定的操作序列已存入一维数组A中。

intJudge(charA[])

//判断字符数组A中的输入输出序列是否是合法序列。如是,返回true,否那么返回false。

{i=0;//i为下标。

j=k=0;//j和k分别为I和字母O的的个数。

while(A[i]!=‘\0’)//当未到字符数组尾就作。

{switch(A[i])

{case‘I’:j++;break;//入栈次数增1。

case‘O’:

k++;if(kj){printf(“序列非法\n”);e*it(0);}

}

i++;//不论A[i]是‘I’或‘O’,指针i均后移。}

if(j!=k){printf(“序列非法\n”);return(false);}

else{printf(“序列合法\n

2022年上半年安徽省JAVA最新版本入门

”);return(true);}

}//算法结束。

43、假设第n件物品能放入背包,那么问题变为能否再从n-1件物品中选出假设干件放入背包〔这时背包可放入物品的重量变为s-w[n]〕。假设第n件物品不能放入背包,那么考虑从n-1件物品选假设干件放入背包〔这时背包可放入物品仍为s〕。假设最终s=0,那么有一解;否那么,假设s0或虽然s0但物品数n1,那么无解。

〔1〕s-w[n],n-1//Knap(s-w[n],n-1)=true

〔2〕s,n-1//Knap←Knap(s,n-1)

44、依据二叉排序树中序遍历所得结点值为增序的性质,在遍历中将当前遍历结点与其前驱结点值比较,即可得出结论,为此设全局指针变量pre〔初值为null〕和全局变量flag,初值为true。假设非二叉排序树,那么置flag为false。

#definetrue1

#definefalse0

typedefstructnode

{datatypedata;structnode*llink,*rlink;}*BTree;

voidJudgeBST〔BTreet,intflag〕

//判断二叉树是否是二叉排序树,本算法结束后,在调用程序中由flag得出结论。

{if〔t!=nullflag〕

{Judgebst〔t-llink,flag〕;//中序遍历左子树

if〔pre==null〕pre=t;//中序遍历的第一个结点不必判断

elseif〔pre-datat-data〕pre=t;//前驱指针指向当前结点

else{flag=flase;}//不是完全二叉树

Judgebst〔t-rlink,flag〕;//中序遍历右子树

}//JudgeBST算法结束

45、由于后序遍历栈中保留当前结点的祖先的信息,用一变量保存栈的最高栈顶指针,每当退栈时,栈顶指针高于保存最高栈顶指针的值时,那么将该栈倒入帮助栈中,帮助栈始终保存最长路径长度上的结点,直至后序遍历完毕,那么帮助栈中内容即为所求。

voidLongestPath(BiTreebt)//求二叉树中的第一条最长路径长度

{BiTreep=bt,l[],s[];//l,s是栈,元素是二叉树结点指针,l中保留当前最长路径中的结点

inti,top=0,tag[],longest=0;

while(p||top0)

{while(p){s[++top]=p;tag[top]=0;p=p-Lc;}//沿左分枝向下

if(tag[top]==1)//当前结点的右分枝已遍历

{if(!s[top]-Lc!s[top]-Rc)//只有到叶子结点时,才查看路径长度

if(toplongest){for(i=1;i=top;i++)l[i]=s[i];longest=top;top--;}

//保留当前最长路径到l栈,记住最高栈顶指针,退栈

}

elseif(top0){tag[top]=1;p=s[top].Rc;}//沿右子分枝向下

}//while(p!=null||top0)

}//结束LongestPath

46、假设K1,…,Kn是n个关键词,试解答:

试用二叉查找树的插入算

法建立一棵二叉查找树,即当关键词的插入次序为K1,K2,…,Kn时,用算法建立一棵以LLINK/RLINK链接表示的二叉查找树。

47、我们用l代表最长平台的长度,用k指示最长平台在数组b中的起始位置〔下标〕。用j记住局部平台的起始位置,用i指示扫描b数组的下标,i从0开始,

2022年上半年安徽省JAVA最新版本入门

依次和后续元素比较,假设局部平台长度〔i-j〕大于l时,那么修改最长平台的长度k〔l=i-j〕和其在b中的起始位置〔k=j〕,直到b数组结束,l即为所求。

voidPlatform(intb[],intN)

//求具有N个元素的整型数组b中最长平台的长度。

{l=1;k=0;j=0;i=0;

while(in-1)

{while(in-1b[i]==b[i+1])i++;

if(i-j+1l){l=i-j+1;k=j;}//局部最长平台

i++;j=i;}//新平台起点

printf(“最长平台长度%d,在b数组中起始下标为%d”,l,k);

}//Platform

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

49、设一棵树T中边的集合为{(A,B),(A,C),(A,D),(B,E),(C,F),(C,G)},要求用孩子兄弟表示法〔二叉链表〕表示出该树的存储结构并将该树转化成对应的二叉树。

50、此题要求建立有序的循环链表。从头到尾扫描数组A,取出A[i]〔0=in〕,然后到链表中去查找值为A[i]的结点,假设查找失败,那么插入。

LinkedListcreat(ElemTypeA[],intn)

//由含n个数据的数组A生成循环链表,要求链表有序并且无值重复结点

{LinkedListh;

h=(LinkedList)malloc(sizeof(LNode));//申请结点

h-ne*t=h;//形成空循环链表

for(i=0;in;i++)

{pre=h;

p=h-ne*t;

while(p!=hp-dataA[i])

{pre=p;p=p-ne*t;}//查找A[i]的插入位置

if(p==h||p-data!=A[i])//重复数据不再输入

{s=(LinkedList)malloc(sizeof(LNode));

s-data=A[i];pre-ne*t=s;s-ne*t=p;//将结点s链入链表中

}

}//for

return(h);

}算法结束

51、我们可用“破圈法”求解带权连通无向图的一棵最小代价生成树。所谓“破圈法”就是“任取一圈,去掉圈上权最大的边”,反复执行这一步骤,直到没有圈为止。请给出用“破圈法”求解给定的带权连通无向图的一棵最小代价生成树的具体算法,并用程序实现你所给出的算法。注:圈就是回路。

52、由二叉树的前序遍历和中序遍历序列能确定唯一的一棵二叉树,下面程序的作用是实现由已知某二叉树的前序遍历和中序遍历序列,生成一棵用二叉链表表示的二叉树并打印出后序遍历序列,请写出程序所缺的语句。

#defineMA*100

typedefstructNode

{charinfo;structNode*llink,*rlink;}TNODE;

charpred[MA*],inod[MA*];

main(intargc,int**argv)

{TNODE*root;

if(argc3)e*it0;

strcpy(pred,argv[1]);strcpy(inod,argv[2]);

root=restore(pred,inod,strlen(pred));

postorder(root);

}

TNODE*restore(char*ppos,char*ipos,intn)

{TNODE*ptr;char*rpos;intk;

if(n=0)returnNULL;

ptr-info=(1)_______;

for((2)_______;rposipos+n;rpos++)if(*rpos==*ppos)break;

k=(3)_______;

ptr-llink=restore(ppos+1,(4)_______,k);

ptr-rlink=restore((5)_______+k,rpos+1,n-1-k);

returnptr;

}

postorder(TNODE*ptr)

{if(p

2022年上半年安徽省JAVA最新版本入门

tr=NULL)return;

postorder(ptr-llink);postorder(ptr-rlink);printf(“%c”,ptr-info);

}

53、设一棵树T中边的集合为{(A,B),(A,C),(A,D),(B,E),(C,F),(C,G)},要求用孩子兄弟表示法〔二叉链表〕表示出该树的存储结构并将该树转化成对应的二叉树。

54、4、voidLinkList_reverse(LinklistL)

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

{

p=L-ne*t;q=p-ne*t;s=q-ne*t;p-ne*t=NULL;

while(s-ne*t)

{

q-ne*t=p;p=q;

q=s;s=s-ne*t;//把L的元素逐个插入新表表头

}

q-ne*t=p;s-ne*t=q;L-ne*t=s;

}//LinkList_reverse

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

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

constn=用户定义的顶点数;

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

voiddfs(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-adjve*]==0)dfs(p-adjve*);

p=p-ne*t;}//while

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

}//dfs

voidJudgeRoot()

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

{staticinti;

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

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

}//JudgeRoot

算法中打印根时,输出顶点在邻接表中的序号〔下标〕,假设要输出顶点信息,可运用g[i].verte*。

56、有一个带头结点的单链表,每个结点包括两个域,一个是整型域info,另一个是指向下一个结点的指针域ne*t。假设单链表已建立,设计算法删除单链表中全部重复涌现的结点,使得info域相等的结点只保留一个。

#includestdio.h

typedefchardatatype;

typedefstructnode{

datatypedata;

structnode*ne*t;

}listnode;

typedeflistnode*linklist;

/**/

/*删除单链表中重复的结点*/

/**/

linklistdeletelist(linklisthead)

{listnode*p,*s,*q;

p=head-ne*t;

while(p)

{s=p;

q=p-ne*t;

while(q)

if(q-data==p-

data)

{s-ne*t=q-ne*t;free(q);

q=s-ne*t;}

else

{s=q;/*找与P结点值相同的结点*/

q=q-ne*t;

}

p=p-ne*t;

}

returnhead

2022年上半年安徽省JAVA最新版本入门

;

}

57、4、voidLinkList_reverse(LinklistL)

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

{

p=L-ne*t;q=p-ne*t;s=q-ne*t;p-ne*t=NULL;

while(s-ne*t)

{

q-ne*t=p;p=q;

q=s;s=s-ne*t;//把L的元素逐个插入新表表头

}

q-ne*t=p;s-ne*t=q;L-ne*t=s;

}//LinkList_reverse

58、设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、B和C用链式存储结构表示。

typedefstructnode{intdata;structnode*ne*t;}lklist;

voidintersection(lklist*ha,lklist*hb,lklist*hc)

{

lklist*p,*q,*t;

for(p=ha,hc=0;p!=0;p=p-ne*t)

{for(q=hb;q!=0;q=q-ne*t)if(q-data==p-data)break;

if(q!=0){t=(lklist*)malloc(sizeof(lklist));t-data=p-data;t-ne*t=hc;hc=t;}

}

}

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

60、连通图的生成树包括图中的全部n个顶点和足以使图连通的n-1条边,最小生成树是边上权值之和最小的生成树。故可按权值从大到小对边进行排序,然后从大到小将边删除。每删除一条当前权值最大的边后,就去测试图是否仍连通,假设不再连通,那么将该边复原。假设仍连通,继续向下删;直到剩n-1条边为止。

voidSpnTree(AdjListg)

//用“破圈法”求解带权连通无向图的一棵最小代价生成树。

{typedefstruct{inti,j,w}node;//设顶点信息就是顶点编号,权是整型数

nodeedge[];

scanf(%d%d,e,n);//输入边数和顶点数。

for(i=1;i=e;i++)//输入e条边:顶点,权值。

scanf(%d%d%d,edge[i].i,edge[i].j,edge[i].w);

for(i=2;i=e;i++)//按边上的权值大小,对边进行逆序排序。

{edge[0]=edge[i];j=i-1;

while(edge[j].wedge[0].w)edge[j+1]=edge[j--];

edge[j+1]=edge[0];}//for

k=1;eg=e;

while(eg=n)//破圈,直到边数e=n-1.

{if(connect(k))//删除第k条边假设仍连通。

{edge[k].w=0;eg--;}//测试下一条边edge[k],权值置0表示该边被删除

k++;//下条边

}//while

}//算法结束。

connect()是测试图是否连通的函数,可用图的遍历实现,

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

62、将顶点放在两个集合V1和V2。对每个顶点,检查其和邻接点是否在同一个集合中,如是,那么为非二部图。为此,用整数1和2表示两个集合。再用一队列结构存放图中访问的顶点。

intBPGraph(AdjMatri*

g)

//判断以邻接矩阵表示的图g是否是二部图。

{ints[];//顶点向量,元素值表示其属于那个集合〔值1和2表示两个集合〕

intQ[];//Q为队列,元素为图的顶点,这里设顶点信息就是顶点编号。

intf=0,r,visited[];//f和r分别是队列的头尾指

2022年上半年安徽省JAVA最新版本入门

针,visited[]是访问数组

for(i=1;i=n;i++){visited[i]=0;s[i]=0;}//初始化,各顶点未确定属于那个集合

Q[1]=1;r=1;s[1]=1;//顶点1放入集合S1

while(fr)

{v=Q[++f];if(s[v]==1)jh=2;elsejh=1;//预备v的邻接点的集合号

if(!visited[v])

{visited[v]=1;//确保对每一个顶点,都要检查与其邻接点不应在一个集合中

for(j=1,j=n;j++)

if(g[v][j]==1){if(!s[j]){s[j]=jh;Q[++r]=j;}//邻接点入队列

elseif(s[j]==s[v])return(0);}//非二部图

}//if(!visited[v])

}//while

return(1);}//是二部图

[算法争论]题目给的是连通无向图,假设非连通,那么算法要修改。

63、将顶点放在两个集合V1和V2。对每个顶点,检查其和邻接点是否在同一个集合中,如是,那么为非二部图。为此,用整数1和2表示两个集合。再用一队列结构存放图中访问的顶点。

intBPGraph(AdjMatri*g)

//判断以邻接矩阵表示的图g是否是二部图。

{ints[];//顶点向量,元素值表示其属于那个集合〔值1和2表示两个集合〕

intQ[];//Q为队列,元素为图的顶点,这里设顶点信息就是顶点编号。

intf=0,r,visited[];//f和r分别是队列的头尾指针,visited[]是访问数组

for(i=1;i=n;i++){visited[i]=0;s[i]=0;}//初始化,各顶点未确定属于那个集合

Q[1]=1;r=1;s[1]=1;//顶点1放入集合S1

while(fr)

{v=Q[++f];if(s[v]==1)jh=2;elsejh=1;//预备v的邻接点的集合号

if(!visited[v])

{visited[v]=1;//确保对每一个顶点,都要检查与其邻接点不应在一个集合中

for(j=1,j=n;j++)

if(g[v][j]==1){if(!s[j]){s[j]=jh;Q[++r]=j;}//邻接点入队列

elseif(s[j]==s[v])return(0);}//非二部图

}//if(!visited[v])

}//while

return(1);}//是二部图

[算法争论]题目给的是连通无向图,假设非连通,那么算法要修改。

64、设有一组初始记录关键字序列〔K1,K2,…,Kn〕,要求设计一个算法能够在O(n)的时间繁复度内将线性表划分成两部分,其中左半部分的每个关键字均小于Ki,右半部分的每个关键字均大于等于Ki。

voidquickpass(intr[],ints,intt)

{

inti=s,j=t,*=r[s];

while(ij){

while(ijr[j]*)j=j-1;if(ij){r[i]=r[j];i=i+1;}

while(ijr[i]*)i=i+1;if(ij){r[j]=r[i];j=j-1;}

}

r[i]=*;

}

65、设一棵树T中边的集合为{(A,B),(A,C),(A,D),(B,E),(C,F),(C

,G)},要求用孩子兄弟表示法〔二叉链表〕表示出该树的存储结构并将该树转化成对应的二叉树。

66、连通图的生成树包括图中的全部n个顶点和足以使图连通的n-1条边,最小生成树是边上权值之和最小的生成树。故可按权值从大到小对边进行排序,然后从大到小将边删除。每删除一条当前权值最大的边后,

2022年上半年安徽省JAVA最新版本入门

就去测试图是否仍连通,假设不再连通,那么将该边复原。假设仍连通,继续向下删;直到剩n-1条边为止。

voidSpnTree(AdjListg)

//用“破圈法”求解带权连通无向图的一棵最小代价生成树。

{typedefstruct{inti,j,w}node;//设顶点信息就是顶点编号,权是整型数

nodeedge[];

scanf(%d%d,e,n);//输入边数和顶点数。

for(i=1;i=e;i++)//输入e条边:顶点,权值。

scanf(%d%d%d,edge[i].i,edge[i].j,edge[i].w);

for(i=2;i=e;i++)//按边上的权值大小,对边进行逆序排序。

{edge[0]=edge[i];j=i-1;

while(edge[j].wedge[0].w)edge[j+1]=edge[j--];

edge[j+1]=edge[0];}//for

k=1;eg=e;

while(eg=n)//破圈,直到边数e=n-1.

{if(connect(k))//删除第k条边假设仍连通。

{edge[k].w=0;eg--;}//测试下一条边edge[k],权值置0表示该边被删除

k++;//下条边

}//while

}//算法结束。

connect()是测试图是否连通的函数,可用图的遍历实现,

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

voidHospital(AdjMatri*w,intn)

//在以邻接带权矩阵表示的n个村庄中,求医院建在何处,使离医院最远的村庄到医院的路径最短。

{for(k=1;k=n;k++)//求任意两顶点间的最短路径

for(i=1;i=n;i++)

for(j=1;j=n;j++)

if(w[i][k]+w[k][j]w[i][j])w[i][j]=w[i][k]+w[k][j];

m=MA*INT;//设定m为机器内最大整数。

for(i=1;i=n;i++)//求最长路径中最短的一条。

{s=0;

for(j=1;j=n;j++)//求从某村庄i〔1=i=n〕到其它村庄的最长路径。

if(w[i][j]s)s=w[i][j];

if(s=m){m=s;k=i;}//在最长路径中,取最短的一条。m记最长路径,k记出发顶点的下标。

Printf(“医院应建在%d村庄,到医院距离为%d\n”,i,m);

}//for

}//算法结束

对以上实例模拟的过程略。各行中最大数依次是9,9,6,7,9,9。这几个最大数中最小者为6,故医院应建在第三个村庄中,离医院最远的村庄到医院的距离是6。

1、对图1所示的连通网G,

请用Prim算法构造其最小生成树〔每选取一条边画一个图〕。

68、矩阵中元素按行和按列都已排序,要求查找时间繁复度为O〔m+n〕,因此不能采纳常规的二层循环的查找。可以先从右上角〔i=a,j=d〕元素与*比较,只有三种状况:一是A[i,j]*,这状况下向j小的方向继续查

2022年上半年安徽省JAVA最新版本入门

找;二是A[i,j]*,下步应向i大的方向查找;三是A[i,j]=*,查找胜利。否那么,假设下标已超出范围,那么查找失败。

voidsearch(datatypeA[][],inta,b,c,d,datatype*)

//n*m矩阵A,行下标从a到b,列下标从c到d,本算法查找*是否在矩阵A中.

{i=a;j=d;flag=0;//flag是胜利查到*的标识

while(i=bj=c)

if(A[i][j]==*){flag=1;break;}

elseif(A[i][j]*)j--;elsei++;

if(flag)printf(“A[%d][%d]=%d”,i,j,*);//假定*为整型.

elseprintf(“矩阵A中无%d元素”,*);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论