数据结构十Word文件下载.docx
- 文档编号:20472517
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:13
- 大小:46.78KB
数据结构十Word文件下载.docx
《数据结构十Word文件下载.docx》由会员分享,可在线阅读,更多相关《数据结构十Word文件下载.docx(13页珍藏版)》请在冰豆网上搜索。
begin
write('
usewhichfile?
'
);
readln(name);
assign(fdat,name);
reset(fdat);
read(fdat,n);
fori:
=1tondo
forj:
read(fdat,data[i,j]);
=1tondowrite(data[i,j]:
5);
writeln;
end;
functioncolorsame(s:
byte):
boolean;
{判断相邻点是否同色}
i:
colorsame:
=false;
=1tos-1do
if(data[i,s]=1)and(color[i]=color[s])thencolorsame:
=true;
procedureprint;
{输出}
=1tondowrite(color[i]:
2);
inc(total);
writeln('
con:
total);
proceduretry(s:
byte);
{递归搜索}
ifs>
7thenprint
else
=0;
repeat
inc(i);
color[s]:
=i;
ifnot(colorsame(s))thentry(s+1);
untili=4
begin{主源程序如下}
getdata;
try
(1);
Total='
readln;
end.
fdat文件内容:
7
0100101
1001010
0000011
0100011
1000001
0111000
1011100
例2对图2从V1点出发,沿着边系统地访问该图中其它所有的顶点一次且仅一次。
(用两种不同的解法)
图2 图3
从图上某点出发,沿边访问图中其它所有的顶点一次且仅一次,称为图的遍历。
图的遍历有两种方式:
深度优先搜索遍历与广度优先搜索遍历。
(一)深度优先搜索遍历算法
⒈以给定的某个顶点V0为起始点,访问该顶点;
⒉选取一个与顶点V0相邻接且未被访问过的顶点V1,用V1作为新的起始点,重复上述过程;
⒊当到达一个其所有邻接的顶点都已被访问过的顶点Vi时,就退回到新近被访问过的顶点Vi- 1,继续访问Vi-1尚未访问的邻接点,重复上述搜索过程;
⒋直到从任意一个已访问过的顶点出发,再也找不到未被访问过的顶点为止,遍历便告完成。
这种搜索的次序体现了向纵深发展的趋势,所以称之为深度优先搜索。
图13.14中从V1出发的一种深度优先搜索访问顺序:
V1-->
V2-->
V4-->
V8-->
V5-->
V6-->
V3-->
V7
(二)广度优先搜索遍历算法
⒈从图中的某一顶点V0开始,先访问V0;
⒉访问所有与V0相邻接的顶点V1,V2,......,Vt;
⒊依次访问与V1,V2,......,Vt相邻接的所有未曾访问过的顶点;
⒋循此以往,直至所有的顶点都被访问过为止。
这种搜索的次序体现沿层次向横向扩长的趋势,所以称之为广度优先搜索。
图13.14中,从V1出发的一种广度优先搜索访问顺序为:
V7-->
V8
源程序如下中数据采用邻接表方式表示。
邻接表如图13.15所示。
存储邻接表数据需要三个变量,一个存储结点的内容,一个存储结点指向下一个结点的指针,一个存储每个链表的链头指针。
设数组变量A(i,0)存放结点,A(i,1)存放结点的指针,H存放链头指针。
数据存放形式如表1所示。
表1
源程序如下:
programbianli(input,output,fdat);
const
max=10;
type
gradat=array[1..max,1..max]ofinteger;
way=setof1..max;
var
data:
n,k:
path:
already:
way;
m:
proceduregetdata;
name:
fdat:
i,j:
begin
write('
readln(name);
assign(fdat,name);
reset(fdat);
read(fdat,n);
fori:
j:
repeat
inc(j);
read(fdat,data[i,j]);
untildata[i,j]=0;
end;
=1;
['
i:
2,'
]'
whiledata[i,j]<
>
0do
write(data[i,j]:
3);
writeln;
procedureprint;
i:
=1tondowrite(path[i]:
procedurewidth(s:
{广度优先搜索遍历}
useful,next:
k:
path[k]:
=s;
useful:
=[s];
next:
=[];
ifiinusefulthen
ifnot(data[i,j]inalready)then
=next+[data[i,j]];
=already+[data[i,j]];
inc(k);
=data[i,j];
inc(j)
=next;
untilk=n;
proceduredeepth(s:
{深度优先搜索遍历}
=already+[s];
whiledata[s,i]<
ifnot(data[s,i]inalready)
thendeepth(data[s,i]);
inc(i);
getdata;
Whichdoyouwanttobegin:
readln(m);
until(m>
0)and(m<
=n);
deepth(m);
Deeppathis:
'
print;
width(m);
Widepathis:
readln;
end.
fdat文件数据:
8
230
1450
1670
280
380
45670
例3如图4所示,从A到B有好几条可供选择的路线,每条路线的长度均标示在图上,问选择什么样的路线,可使从A到B所走的路径最短?
图4
分析:
在一个有向图G=(V,E)中,给定一个始点V1和终点Vp,对每条弧(Vi,Vj)相应地有一个权W(i,j),最短路问题就是要求从始点V1到终点Vp的一条路径,使其在所有从V1到Vp的路径中,它是总权最小的一条。
当所有的W(i,j)>
=0时,解决最短路径问题的比较好的方法是Dijkstra方法。
它是荷兰计算机科学家(E.W.Dijkstra)于1959年提出的。
这个方法不仅求出了从A到顶点B的最短路径,而且求出了从A到各顶点的最短路径。
算法步骤:
从V1开始,给每一个顶点赋予一个标号,标号分为两种:
(1)T标号--V1到该顶点的最短路径的上界(临时标号);
(2)P标号--V1到该顶点的最短路径(固定标号)。
若某一顶点已得到P标号,则表明已求出V1到该点的最短路径,凡未得到P标号的顶点,一律标上T标号。
算法的每一步把某一顶点的T标号改变为P标号,最多经过(n-1)步(n为顶点个数),即可得到从V1到每一个顶点的最短路径。
⒈在初始状态下,令P(V1)=0,T(Vi)=+∞(i=1,2,3,......,n),反复执行下面两个步骤;
⒉设Vi是已经得到P标号的点,考虑所有满足下列条件的顶点Vi的集合B:
B={Vj|(Vi,Vj)E且Vj是T标号}
将集合B中的每一个顶点Vj的T标号修改为:
min{T(Vj),P(Vi)+W(i,j)}
⒊若G中已没有T标号的顶点,则结束,否则,将集合B中最小者的T标号改变为P标号,然后转到2。
下面,以求V1到V7的最短路径为例,说明Dijkstra方法:
开始,令P(V1)=0,T(Vj)=+∞(j=1,2,3,...,7)
第一步:
考虑所有与V1相联且标有T标号的点的集合:
B={V2,V3,V4};
修改集合B中元素的T标号
T(V2)=min{T(V2),P(V1)+W(1,2)}=min{+∞,2}=2
T(V3)=min{T(V3),P(V1)+W(1,3)}=min{+∞,5}=5
T(V4)=min{T(V4),P(V1)+W(1,4)}=min{+∞,3}=3
将其中最小者改为标号:
P
(2)=2
第二步:
考虑所有与V1,V2相联且标有T标号的点集合:
B={V3,V4,V6};
T(V3)=min{T(V3),P
(2)+W(2,3)}=min{5,4}=4
T(V4)=3(同前面求法)
T(V6)=min{T(V6),P
(2)+W(2,6)}=min{+∞,9}=9
将其中最小者改变为P标号,P(V4)=3
第三步:
考虑所有与V1,V2,V4相联且标有T标号的点的集合:
B={V3,V5,V6};
T(V3)=4
T(V5)=min{T(V5),P(V4)+W(4,5)}=min{+∞,8}=8
T(V6)=9
将其中最小者改变为P标号:
P(V3)=4
第四步:
考虑所有与V1,V2,V3,V4相联且标有T标号的点的集合:
B={V5,V6};
修改集合B中的元素的T标号
T(V5)=min{T(V5),P(V3)+W(3,5)}=min{8,7}=7
T(V6)=min{T(V6),P(V3)+W(3,6)}=min{9,9}=9
P(V5)=7
第五步:
考虑所有与V1,V2,V3,V4,V5相联且标有T标号的点的集合:
B={V6,V7};
T(V6)=min{T(V6),P(V5)+W(5,6)}=min{9,8}=8
T(V7)=min{T(V7),P(V5)+W(5,7)}=min{+∞,14}=14
将其中最小者改变为T标号:
P(V6)=8
第六步:
考虑所有与V1,V2,V3,V4,V5,V6相联且标有T标号的点的集合:
B={V7};
修改集合中B元素的T标号
T(V7)=min{T(V7),P(V6)+W(6,7)}=min{14,13}=13
P(V7)=13
至此,所有顶点的T标号均已改变为P标号了,说明V1到各顶点的最短路径已全部找到。
programleastway;
gradat=array[1..max,1..max]ofreal;
a,b:
n:
path,path1:
least:
real;
forj:
Pathis:
a:
whilepath[i]<
write(path[i]:
writeln('
Longth='
least);
procedurelookfor(d:
s:
way);
{求最短路径}
begin;
if(data[d,j]<
0)andnot(jinalready)then
path1[k]:
=j;
if(j=b)and(s+data[d,j]<
least)then
=path1;
=s+data[d,j];
path[k+1]:
end
elselookfor(j,s+data[d,j],k+1,already+[j]);
Fromwhich>
readln(a);
Towhich>
readln(b);
=1e+36;
lookfor(a,0,1,[a]);
7
0253000
0020070
0001350
0000500
0000017
0000005
0000000
例4图5所示的网络代表6个城市间的交通网,边上权是公路的造价,现在要用公路把6个城市联系起来,这要修筑5条公路,如何设计使得这5条公路总的造价最小。
图5
这是一个最小生成树问题,所谓最小生成树就是从某个顶点出发遍历图中的各点,且使各边权的总和为最小,一个网络的最小生成树不一定是唯一的。
图6是图5的两个最小生成树,它们权的总和均为5+16+11+6+18=56。
图6
构成最小生成树的典型算法有Prime算法与Kruskal算法等。
本题解答用Kruskal算法:
⒈先把平面上各顶点之间的边统统擦掉,只剩下一些孤立的点;
⒉把各边的长度按从小到大的次序排列好;
⒊按从小到大的次序把每边加到图中去,每加进去一条边,就判断一下是否产生回路?
没有回路就加进去下一条边;
若产生回路就放弃这条边,而考虑下一条边,碰到两条等长的边,可任取一条;
⒋重复步骤3,直至加满(n-1)条边,就把n个顶点连接起来了,且边长总和为最小。
programleastcost;
cost:
array[1..2,1..max]ofbyte;
=1ton-1do
Roadside:
path[1,i]:
3,path[2,i]:
cost);
procedurelookfor(varn1,n2:
{查找这一轮中的最小边}
ifiinalreadythen
if(not(jinalready))and(data[i,j]<
0)and(data[i,j]<
m)then
n1:
n2:
procedureadd;
{记录最小生成树及总造价}
lookfor(i,j);
=already+[j];
=cost+data[i,j];
path[1,k]:
path[2,k]:
untilalready=[1..n];
=[1];
add;
fdat文件数据:
6
016001921
16056011
050600
06601814
190018033
2111014330
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构