図のストレージ構造。
隣接行列
隣接行列は、隣接する頂点間の関係を示す行列です。
どの2つの辺が図に接続されているがそれ以外の場合は、1 0ではありません。
VI VJ有向グラフ点は、そうでなければ無限大と呼ばれる、WIJで示され
利点:2つの頂点の間にエッジが存在するか否かを容易決意、頂点の計算を容易にする(無向グラフ:行動度;有向グラフ:度としての動作)
デメリット頂点を追加したり削除したりすることは容易ではない。不便側の統計数、高空間複雑;:
隣接リスト
隣接リストは、図の鎖メモリ構造です。
隣接テーブルに、図VI、VIおよびリンクされたリスト内の隣接頂点ポイントの各頂点のための単一のリストの確立。
利点:頂点の追加や削除が容易;辺の統計数を容易にする、高いスペース効率。
短所:簡単に頂点間のエッジがあるか否かを決定するためではない。頂点の各々に度を算出するのは容易ではありません。
クロスリスト
クロスリストにリンクされた合成リストは、隣接するテーブルで得られた、図1の隣接リストの逆されると見なすことができます。各アークは、ノードに対応する、各頂点に対応するノードを有しています。有向グラフに適し。
tailvex | headvex | HLINK | TLINK | インフォ |
データ | firstin | 先出し |
アーク接合点:尾部ドメイン(tailvex)とヘッダ(headvex)アークにアーク図中最初の2つの頂点の位置の円弧端、ヘッドアークに向け同じ鎖ドメインHLINKアーク、情報フィールド点を示します関連情報。同一鎖上の同一のヘッドアークは、各円弧の端部は、同じ鎖上で同じです。
第1ノードは、そのような名前の頂点として、頂点ノードであり、前記頂点データ・フィールドを格納関連情報; firstin先出し二鎖ドメイン、ヘッドに頂点ポインティング又は第一弧の端アークノード。
隣接するマルチテーブル
隣接するマルチテーブルクロスとのリストに類似した構造の適切な無向グラフ。
マーク | ivex | ILINK | jvex | JLINK | インフォ |
データ | firstedge |
フラグストリップエッジが探索されているかどうかにシンボルドメインとしてエッジノード、マーク、IVEX頂点及びエッジが図中の二つの位置の取り付けのためjvex、iLinkはエッジが頂点IVEXの次の行に取り付けられ、JLINKに関連したエッジや各種情報を指すように頂点ポイントjvex、情報ポインタフィールドの下側に取り付けられました
頂点ノード、情報が格納された頂点のデータフィールドに関連付けられている側、firstedgeフィールドが最初の頂点に取り付けられた側を示しています。
トラバースグラフ
図トラバーサルは、図面から頂点、方法図形の全ての頂点へのいくつかのアクセスに応じて一度だけアクセスされます。
深さ優先探索(DFS)
次のように検索処理の深さ優先探索は以下のとおりです。
1、図から頂点v、アクセスV
2、ちょうど訪問した隣人を見つけるためには、頂点へのアクセスの頂点の最初の訪問ではありません。頂点への新しい頂点、頂点が訪問した隣人を訪問されていないだけになるまでまで、この手順を繰り返します
図3は、隣接する訪問し、未訪問の頂点はまだ未訪問の頂点に隣接するノードを見つける点に戻る前に、頂点を訪問しました
4.繰り返し手順2と3、図中の全ての頂点が訪問されてまで、検索が終了します。
アルゴリズムのステップ:
図1に示すように、図面から頂点v、ACCESS vは、訪問並置[V]の値が真であります
図2に示すように、図中の全ての頂点が訪問されるまで訪問[W]は、再帰的トラバースWから偽である場合、およびすべての隣接点は、wがVチェック
アルゴリズム(図通信、隣接行列を達成するために)。
bool visited[MVNum];//初始化为false
void DFS(Graph G,int V){
cout<<v;
visited[v]=true;
for(w=0;w<G.vexnum;w++)
if(G.arcs[v][w]!=0&&!visited[w]) DFS(G,w);
}
アルゴリズム(図非通信)
void DFSTraverse(Graph G){
for(v=0;v<G.vexnum;++v)visited[v]=false;
for(v=0;v<G.vexnum;++v)
if(!visited[v]) DFS(G,v);
}
時間計算:隣接行列:はO(n ^ 2);隣接テーブル:O(N + E)。
幅優先探索(BFS)
次のようにBFSトラバーサルは次のとおりです。
1、図から頂点v、アクセスV
2、およびVの各訪問は隣人を訪れたことはありません
3は、それぞれ、順次隣人に隣接して、アクセスポイントから「前に訪れた頂点隣接点」「アクセスした後、隣接する頂点」の前にアクセスされています。図アバットメントポイントがアクセスされたすべての頂点まで繰り返しステップ3がアクセスされます。
アルゴリズムのステップ:
1、描画、アクセスvから頂点vは、[V]チームのVに、その後、真で訪れた並置します
2、のように長い行列が空でないとして、次の操作を繰り返します。
(1)Uがヘッドをデキューチームポイント。
偽である[W]は、訪問した場合(2)、順次U W全ての隣接点を確認し、Wアクセスは、その後、Wチームに、真である[W]訪問並置します。
アルゴリズム(隣接行列):
void BFS(Graph G,int v){
cout<<v;
visited[v]=true;
initQueue(Q);
EnQueue(Q,v);
while(!QueueEmpty(Q)){
DeQueue(Q,u);
for(w=0;w<G.vexnum;w++){
if(G.arcs[u][w]!=0&&!visited[w]){
cout<<w;
visited[w]=true;
EnQueue(Q,w);
}
}
}
}
時間計算:隣接行列:はO(n ^ 2);隣接テーブル:O(N + E)
アプリケーションマップ
最小スパニングツリー
プリム法
U0 V0が、それが最小のノートをとる場合には隣人と呼ばながら選択された設定点UとU0、V0で表さ最新セットポイントを非選択点Vを探して、U濃度は、V0を加え
0の値は、セットポイントUに追加されました
V1 | v2の | V3 | V4 | V5 | V6 | |
0 | 6 | 1 | 5 | INF | INF | (V1、V3)、コスト= 1 |
0 | 5 | 0 | 5 | 6 | 4 | (V3、V6)、コスト= 4 |
0 | 5 | 0 | 2 | 6 | 0 | (V6、V4)、コスト= 2 |
0 | 5 | 0 | 0 | 6 | 0 | (V3、V2)、コスト= 5 |
0 | 0 | 0 | 0 | 3 | 0 | (V2、V5)、コスト= 3 |
0 | 0 | 0 | 0 | 0 | 0 | 終了 |
コード:
struct edge{
int adjvex; //连接的顶点
int lowcost;
}closedge[maxn];
int Min_edge(edge e[],int n){
int min_edge=INF,min_ans;
for(int i=1;i<=n;++i){
if(e[i].lowcost<min_edge&&e[i].lowcost!=0){
min_edge=e[i].lowcost;
min_ans=i;
}
}
return min_ans;
}
void MiniSpanTree_Prim(AMGraph G,int u){
for(int j=1;j<=G.vexnum;++j){
if(j!=u) closedge[j]={u,G.arcs[u][j]};//初始化
}
closedge[u].lowcost=0; //初始 U={u}
for(int i=1;i<G.vexnum;++i){
int x=Min_edge(closedge,G.vexnum);
int u0=closedge[x].adjvex;
int v0=x;
cout<<"<v"<<u0<<",v"<<v0<<">\n";
closedge[x].lowcost=0; //第x个顶点并入U集
for(int j=1;j<=G.vexnum;++j){ //新顶点并入U后,重新选择最小边,更新lowcost
if(G.arcs[x][j]<closedge[j].lowcost)
closedge[j]={x,G.arcs[x][j]};
}
}
}
緻密に適した図は、時間計算量はO(N ^ 2)です。
クラスカル法
そうでない場合は次を選択しながらT内のすべての頂点が同じ連結成分になるまでTがループに形成されていない非連通図無限Tを添加しながら順次選択サイド・バイ・重量昇順ソートは、添加されます。
コード:
void MiniSpanTree_Kruskal(AMGraph &G){
sort(Edge+1,Edge+G.vexnum*2,cmp);
int Vexset[maxn];
for(int i=1;i<=G.vexnum;++i){
Vexset[i]=i;
}
int k=1;
for(int i=1;i<=G.vexnum;++i){
int v1=Edge[k].head;
int v2=Edge[k].tail;
int vs1=Vexset[v1];
int vs2=Vexset[v2];
if(vs1!=vs2){
cout<<"<v"<<Edge[k].head<<",v"<<Edge[k].tail<<">\n";
for(int j=1;j<=G.vexnum;++j){
if(Vexset[j]==vs2)
Vexset[j]=vs1;
}
}
k=k+2;
}
}
最短パス
ダイクストラ法
頂点は、2つのグループに分け:
S:最短パスが設定点を決定された、唯一の初期V0
VS:頂点の集合の最短経路であると判断され、最初にV- {V0}
各頂点V0アルゴリズムが昇順との間の最短経路の長さであろうと、頂点VSの一組ずつをSに添加しました
上記のように、現在の最短経路の各々の動作は、(V0から直接到着する、または他の転送点Sに到達した後)、最小値はS抽出を仕込み、次いで、S = Vまでの最短距離の残りの点を更新します
コード:
void dij(int s){
int minn;//临时保存当前的最短距离
dis[s]=0;
for(int i=1;i<=n;i++){//选出权值最小的点
int ui=-1;//即将加入s集合的顶点的编号
minn=MAX_INT;
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]<minn){
minn=dis[j];
ui=j;
}
}
if(ui==-1) break;
vis[ui]=1;
for(int j=1;j<=n;j++){//更新距离
if(!vis[j]&&dis[j]>dis[ui]+graph[ui][j])
{
dis[j]=dis[ui]+graph[ui][j];
dist[s][j]=dis[j];
}
}
}
return;
}
フロイドのアルゴリズム
比較ブルートアルゴリズム、結果は点間の最短シーク
直接コードに:
void Floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dist[i][k]+dist[k][j]<dist[i][j]){
dist[i][j]=dist[i][k]+dist[k][j];
}
}
}
}
}
トポロジカルソート
AOV-ネットは:;特定のアクティビティが含まれているかの情報は、前提条件や他のいくつかの活動である有向グラフ前に関係の活動をしている円弧と頂点での活動を示します
トポロジカルソートは、すべての頂点がどの満たす直鎖状配列で配置さAOV-ネットワークである:頂点VIにVJネットワークAOV-つのパス、頂点viはVJ前でなければならない線形シーケンスである場合、
アルゴリズムの実装プロセス:
(0度点を削除し、アークから放射され、この操作を繰り返します)
アルゴリズムのステップ:
図1に示すように、頂点配列入次数[]に登録決定、頂点描画0に読み込まれ
2、只要栈不空,则重复以下操作:
(1)将栈顶顶点vi出栈并保存在拓扑序列数组topo中
(2)对顶点vi的每个邻接点vk的入度减1,如果vk入度变为0,vk入栈;
3、如果输出顶点个数少于网中顶点个数,则网中存在有向环,无法进行拓扑排序,否则拓扑排序成功。
时间复杂度:O(n+e)。
关键路径
AOE-网:与AOV-网相对,是以边表示活动的网。
————————————————————————————————————————————————————————
图片来源:https://www.cnblogs.com/wkfvawl/p/9985083.html
https://www.cnblogs.com/lbrs/p/11879357.html
https://blog.csdn.net/qq_41713256/article/details/80805338
注:本文所有内容均来源于《数据结构(C语言第二版)》(严蔚敏老师著)