数据结构

位置:IT落伍者 >> 数据结构 >> 浏览文章

数据结构算法集锦


发布日期:2021年09月04日
 
数据结构算法集锦

数论算法

求两数的最大公约数

function gcd(ab:integer):integer;

begin

if b= then gcd:=a

else gcd:=gcd (ba mod b);

end ;

求两数的最小公倍数

function lcm(ab:integer):integer;

begin

if a

lcm:=a;

while lcm mod b> do inc(lcma);

end;

素数的求法

A小范围内判断一个数是否为质数

function prime (n: integer): Boolean;

var I: integer;

begin

for I:= to trunc(sqrt(n)) do

if n mod I= then begin

prime:=false; exit;

end;

prime:=true;

end;

B判断longint范围内的数是否为素数(包含求以内的素数表)

procedure getprime;

var

ij:longint;

p:array[] of boolean;

begin

fillchar(psizeof(p)true);

p[]:=false;

i:=;

while i< do begin

if p[i] then begin

j:=i*;

while j< do begin

p[j]:=false;

inc(ji);

end;

end;

inc(i);

end;

l:=;

for i:= to do

if p[i] then begin

inc(l);pr[l]:=i;

end;

end;{getprime}

function prime(x:longint):integer;

var i:integer;

begin

prime:=false;

for i:= to l do

if pr[i]>=x then break

else if x mod pr[i]= then exit;

prime:=true;

end;{prime}

图论算法

最小生成树

APrim算法

procedure prim(v:integer);

var

lowcostclosest:array[maxn] of integer;

ijkmin:integer;

begin

for i:= to n do begin

lowcost[i]:=cost[vi];

closest[i]:=v;

end;

for i:= to n do begin

{寻找离生成树最近的未加入顶点k}

min:=maxlongint;

for j:= to n do

if (lowcost[j]) then begin

min:=lowcost[j];

k:=j;

end;

lowcost[k]:=; {将顶点k加入生成树}

{生成树中增加一条新的边k到closest[k]}

{修正各点的lowcost和closest值}

for j:= to n do

if cost[kj]

lowcost[j]:=cost[kj];

closest[j]:=k;

end;

end;

end;{prim}

BKruskal算法(贪心)

按权值递增顺序删去图中的边若不形成回路则将此边加入最小生成树

function find(v:integer):integer; {返回顶点v所在的集合}

var i:integer;

begin

i:=;

while (i<=n) and (not v in vset[i]) do inc(i);

if i<=n then find:=i else find:=;

end;

procedure kruskal;

var

totij:integer;

begin

for i:= to n do vset[i]:=[i];{初始化定义n个集合第I个集合包含一个元素I}

p:=n; q:=; tot:=; {p为尚待加入的边数q为边集指针}

sort;

{对所有边按权值递增排序存于e[I]中e[I]v与e[I]v为边I所连接的两个顶点的序号e[I]len为第I条边的长度}

while p> do begin

i:=find(e[q]v);j:=find(e[q]v);

if i<>j then begin

inc(tote[q]len);

vset[i]:=vset[i]+vset[j];vset[j]:=[];

dec(p);

end;

inc(q);

end;

writeln(tot);

end;

最短路径

A标号法求解单源点最短路径

var

a:array[maxnmaxn] of integer;

b:array[maxn] of integer; {b[i]指顶点i到源点的最短路径}

mark:array[maxn] of boolean;

procedure bhf;

var

bestbest_j:integer;

begin

fillchar(marksizeof(mark)false);

mark[]:=true; b[]:=;{为源点}

repeat

best:=;

for i:= to n do

If mark[i] then {对每一个已计算出最短路径的点}

for j:= to n do

if (not mark[j]) and (a[ij]>) then

if (best=) or (b[i]+a[ij]

best:=b[i]+a[ij]; best_j:=j;

end;

if best> then begin

b[best_j]:=best;mark[best_j]:=true;

end;

until best=;

end;{bhf}

BFloyed算法求解所有顶点对之间的最短路径

procedure floyed;

begin

for I:= to n do

for j:= to n do

if a[Ij]> then p[Ij]:=I else p[Ij]:=; {p[Ij]表示I到j的最短路径上j的前驱结点}

for k:= to n do {枚举中间结点}

for i:= to n do

for j:= to n do

if a[ik]+a[jk]

a[ij]:=a[ik]+a[kj];

p[Ij]:=p[kj];

end;

end;

C Dijkstra 算法

var

a:array[maxnmaxn] of integer;

bpre:array[maxn] of integer; {pre[i]指最短路径上I的前驱结点}

mark:array[maxn] of boolean;

procedure dijkstra(v:integer);

begin

fillchar(marksizeof(mark)false);

for i:= to n do begin

d[i]:=a[vi];

if d[i]<> then pre[i]:=v else pre[i]:=;

end;

mark[v]:=true;

repeat {每循环一次加入一个离集合最近的结点并调整其他结点的参数}

min:=maxint; u:=; {u记录离集合最近的结点}

for i:= to n do

if (not mark[i]) and (d[i]

u:=i; min:=d[i];

end;

if u<> then begin

mark:=true;

for i:= to n do

if (not mark[i]) and (a[ui]+d

d[i]:=a[ui]+d;

pre[i]:=u;

end;

end;

until u=;

end;

计算图的传递闭包

Procedure Longlink;

Var

T:array[maxnmaxn] of boolean;

Begin

Fillchar(tsizeof(t)false);

For k:= to n do

For I:= to n do

For j:= to n do T[Ij]:=t[Ij] or (t[Ik] and t[kj]);

End;

无向图的连通分量

A深度优先

procedure dfs ( nowcolor: integer);

begin

for i:= to n do

if a[nowi] and c[i]= then begin {对结点I染色}

c[i]:=color;

dfs(Icolor);

end;

end;

B 宽度优先(种子染色法)

关键路径

几个定义 顶点为源点n为汇点

a 顶点事件最早发生时间Ve[j] Ve [j] = max{ Ve [j] + w[Ij] }其中Ve () = ;

b 顶点事件最晚发生时间 Vl[j] Vl [j] = min{ Vl[j] – w[Ij] }其中 Vl(n) = Ve(n);

c 边活动最早开始时间 Ee[I] 若边I由表示则Ee[I] = Ve[j];

d 边活动最晚开始时间 El[I] 若边I由表示则El[I] = Vl[k] – w[jk];

若 Ee[j] = El[j] 则活动j为关键活动由关键活动组成的路径为关键路径

求解方法

a 从源点起topsort判断是否有回路并计算Ve;

b 从汇点起topsort求Vl;

c 算Ee 和 El;

拓扑排序

找入度为的点删去与其相连的所有边不断重复这一过程

例 寻找一数列其中任意连续p项之和为正任意q 项之和为负若不存在则输出NO

回路问题

Euler回路(DFS)

定义经过图的每条边仅一次的回路(充要条件图连同且无奇点)

Hamilton回路

定义经过图的每个顶点仅一次的回路

一笔画

充要条件图连通且奇点个数为个或

判断图中是否有负权回路 Bellmanford 算法

x[I]y[I]t[I]分别表示第I条边的起点终点和权共n个结点和m条边

procedure bellmanford

begin

               

上一篇:数据结构之二分查找

下一篇:数据结构考研分类复习真题 第六章 答案 (五)[43]