<P>5.最短路径 </P>
<P>A.标号法求解单源点最短路径: <BR>var a:array[1..maxn,1..maxn] of integer; <BR> b:array[1..maxn] of integer; {b指顶点i到源点的最短路径} <BR> mark:array[1..maxn] of boolean; <BR>procedure bhf; <BR>var best,best_j:integer; <BR>begin <BR> fillchar(mark,sizeof(mark),false); <BR> mark[1]:=true; <BR> b[1]:=0;{1为源点} <BR> repeat best:=0; <BR> for i:=1 to n do <BR> If mark then {对每一个已计算出最短路径的点} <BR> for j:=1 to n do <BR> if (not mark[j]) and (a[i,j] &gt;0) then <BR> if (best=0) or (b+a[i,j]&lt; best) then <BR> begin <BR> best:=b+a[i,j]; best_j:=j; <BR> end; <BR> if best &gt;0 then <BR> begin <BR> b[best_j]:=best;<BR> mark[best_j]:=true; <BR> end; <BR> until best=0; <BR>end;{bhf} </P>
<P>B.Floyed算法求解所有顶点对之间的最短路径: <BR>procedure floyed; <BR>begin <BR> for I:=1 to n do <BR> for j:=1 to n do <BR> if a[I,j] &gt;0 then <BR> p[I,j]:=I else p[I,j]:=0; <BR> {p[I,j]表示I到j的最短路径上j的前驱结点} <BR> for k:=1 to n do {枚举中间结点} <BR> for i:=1 to n do for j:=1 to n do <BR> if a[i,k]+a[j,k]&lt; a[i,j] then <BR> begin <BR> a[i,j]:=a[i,k]+a[k,j]; <BR> p[I,j]:=p[k,j]; <BR> end; <BR>end; </P>
<P>C. Dijkstra 算法: <BR>类似标号法,本质为贪心算法。 <BR>var a:array[1..maxn,1..maxn] of integer; <BR> b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} <BR> mark:array[1..maxn] of boolean; <BR>procedure dijkstra(v0:integer); <BR>begin <BR> fillchar(mark,sizeof(mark),false); <BR> for i:=1 to n do <BR> begin <BR> d:=a[v0,i]; <BR> if d&lt; &gt;0 then <BR> pre:=v0 <BR> else <BR> pre:=0; <BR> end; <BR> mark[v0]:=true; <BR> repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} <BR> min:=maxint; <BR> u:=0; {u记录离1集合最近的结点} <BR> for i:=1 to n do <BR> if (not mark) and (d&lt; min) then <BR> begin <BR> u:=i; min:=d; <BR> end; <BR> if u&lt; &gt;0 then <BR> begin <BR> mark:=true; <BR> for i:=1 to n do <BR> if (not mark) and (a[u,i]+d&lt; d) then <BR> begin <BR> d:=a[u,i]+d; <BR> pre:=u; <BR> end; <BR> end; <BR> until u=0; <BR>end; </P>
<P>D.计算图的传递闭包 <BR>Procedure Longlink; <BR>Var T:array[1..maxn,1..maxn] of boolean; <BR>Begin <BR> Fillchar(t,sizeof(t),false); <BR> For k:=1 to n do <BR> For I:=1 to n do <BR> For j:=1 to n do <BR> T[I,j]:=t[I,j] or (t[I,k] and t[k,j]); <BR>End; </P>
<P>7.排序算法 </P>
<P>A.快速排序: <BR>procedure sort(l,r:integer); <BR>var i,j,mid:integer; <BR>begin <BR> i:=l;j:=r; <BR> mid:=a[(l+r) div 2]; <BR> {将当前序列在中间位置的数定义为中间数} <BR> repeat <BR> while a&lt; mid do inc(i); {在左半部分寻找比中间数大的数} <BR> while mid&lt; a[j] do dec(j);{在右半部分寻找比中间数小的数} <BR> if i&lt; =j then <BR> begin {若找到一组与排序目标不一致的数对则交换它们} <BR> swap(a,a[j]); <BR> inc(i);<BR> dec(j); {继续找} <BR> end; <BR> until i &gt;j; <BR> if l&lt; j then <BR> sort(l,j); {若未到两个数的边界,则递归搜索左右区间} <BR> if i&lt; r then sort(i,r); <BR>end;{sort} </P>
<P>B.插入排序: </P>
<P>procedure insert_sort(k,m:word); {k为当前要插入的数,m为插入位置的指针} <BR>var i:word; p:0..1; <BR>begin <BR> p:=0; <BR> for i:=m downto 1 do <BR> if k=a then exit; <BR> repeat If k &gt;a[m] then <BR> begin <BR> a[m+1]:=k; p:=1; <BR> end <BR> else <BR> begin <BR> a[m+1]:=a[m]; <BR> dec(m); <BR> end; <BR> until p=1; <BR>end;{insert_sort} <BR>l 主程序中为: <BR> a[0]:=0; <BR> for I:=1 to n do insert_sort(b,I-1); </P>
<P>C.选择排序: <BR>procedure sort; <BR>var i,j,k:integer; <BR>begin <BR> for i:=1 to n-1 do <BR> begin <BR> k:=i; <BR> for j:=i+1 to n do <BR> if a[j]&lt; a[k] then <BR> k:=j; {找出a..a[n]中最小的数与a作交换} <BR> if k&lt; &gt;i then <BR> begin <BR> a[0]:=a[k];<BR> a[k]:=a;<BR> a:=a[0]; <BR> end; <BR> end; <BR>end; </P>
<P>D. 冒泡排序 <BR>procedure sort; <BR>var i,j,k:integer; <BR>begin <BR> for i:=n downto 1 do <BR> for j:=1 to i-1 do <BR> if a[j] &gt;a then <BR> begin <BR> a[0]:=a;<BR> a:=a[j];<BR> a[j]:=a[0]; <BR> end; <BR>end; </P>
<P>E.堆排序: <BR>procedure sift(i,m:integer);{调整以i为根的子树成为堆,m为结点总数} <BR>var k:integer; <BR>begin <BR> a[0]:=a; <BR> k:=2*i;{在完全二*树中结点i的左孩子为2*i,右孩子为2*i+1} <BR> while k&lt; =m do <BR> begin <BR> if (k&lt; m) and (a[k]&lt; a[k+1]) then inc(k);{找出a[k]与a[k+1]中较大值} <BR> if a[0]&lt; a[k] then <BR> begin <BR> a:=a[k];<BR> i:=k;<BR> k:=2*i; <BR> end <BR> else <BR> k:=m+1; <BR> end; <BR> a:=a[0]; {将根放在合适的位置} <BR>end; </P>
<P>procedure heapsort; <BR>var j:integer; <BR>begin <BR> for j:=n div 2 downto 1 do sift(j,n); <BR> for j:=n downto 2 do <BR> begin <BR> swap(a[1],a[j]); <BR> sift(1,j-1); <BR> end; <BR>end; </P>
<P>F. 归并排序 <BR>{a为序列表,tmp为辅助数组} <BR>procedure merge(var a:listtype; p,q,r:integer); <BR>{将已排序好的子序列a[p..q]与a[q+1..r]合并为有序的tmp[p..r]} <BR>var I,j,t:integer; <BR> tmp:listtype; <BR>begin <BR> t:=p;<BR> i:=p;<BR> j:=q+1;{t为tmp指针,I,j分别为左右子序列的指针} <BR> while (t&lt; =r) do <BR> begin <BR> if (i&lt; =q){左序列有剩余} and ((j &gt;r) or (a&lt; =a[j])) then {满足取左边序列当前元素的要求} <BR> begin <BR> tmp[t]:=a; inc(i); <BR> end <BR> else <BR> begin <BR> tmp[t]:=a[j];<BR> inc(j); <BR> end; <BR> inc(t); <BR> end; <BR> for i:=p to r do a:=tmp; <BR>end;{merge} </P>
<P>procedure merge_sort(var a:listtype; p,r: integer); {合并排序a[p..r]} <BR>var q:integer; <BR>begin <BR> if p&lt; &gt;r then <BR> begin <BR> q:=(p+r-1) div 2; <BR> merge_sort (a,p,q); <BR> merge_sort (a,q+1,r); <BR> merge (a,p,q,r); <BR> end; <BR>end; <BR>{main} <BR>begin <BR> merge_sort(a,1,n); <BR>end. </P> |