基本的なアルゴリズムとデータ構造コレクション:
https://blog.csdn.net/GD_ONE/article/details/104061907
概要
本稿では、隣接行列と隣接リスト、いいえ、および有向グラフの間の差、および図の緻密スパースグラフ図差の実装を記述する。そして、2つのシナリオを使用すると、保存されました。スパース隣接テーブルストレージ図5を用いて、隣接行列を使用して図の密なストレージ。
有向グラフとの間の差はありません。
特別な有向グラフは有向グラフではありません2点長くないエッジが存在しない限り、何のグラフは有向グラフ両側の2点間に来ていないときにそれを置くように構築され、図にお互いに達することができます。
図粗密グラフ
同じ大きさのオーダーであるスパースグラフは、一般的に1000年変数が1000程度であり、緻密な図は、一般に、点100、及びエッジ10000の数として、点の正方形の辺の数を指しているこのような点の数として、描画点とエッジを指し。
隣接行列
隣接行列を聞きながら非常に深い、非常に強力ですが、実際には、それはありますA二次元配列。大きな疎なグラフの点は、二次元アレイを維持するために使用することができないときに。
有向グラフを考える:
隣接行列Dとして表さ:だから
ここで、INF +無限大、すなわち、しない点と別の点との間に接続されたエッジ。
そうD [i] [j]は点のJ数をポイント数Iとの間の辺の長さ
隣接行列の初期化
なぜなら距離に自分のは0であり、2点間のINFに接続すべきエッジが存在しない場合、これらの2つの場合の最初のものは初期化します。
n個のポイントの合計が存在すると仮定し、隣接行列D設け
コード:
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; i++){
if(i == j){
D[i][j] = 0;
}
else{
D[i][j] = INF;
}
}
}
注:INF通常設定:0x3f3f3f3f
隣接行列を読みます
複数のエッジとループバック
量側は、入力データの側面は、2つの与えられた点の間繰り返されます。
リングは、独自のポイントに接続されているので。
マップとマップの間に違いはありません:
無向グラフは特別な有向グラフである、我々は唯一の有向グラフのエッジを構築するための時間を持っています
質問と可能な重い側ループバックなので、特別審査員の側にそれを読む時間の一部。最短経路問題を求めている場合、例えば、最小側が格納されます。
一般的な形式が読み取られる:( Mエッジの総数を想定し、各列)は、三つの整数、A、B、Wを与えB Wに辺の長さを表します。
for(int i = 1; i <= m; i++){
int a = in.nextInt();
int b = in.nextInt();
int w = in.nextInt();
D[a][b] = Math.min(D[a][b], w); //如果有重边则只存储最短的
}
隣接リスト
隣接リストは、ストレージアレイ+のリンクされたリストで使用され、正確に同じ方法で実現されるジッパーハッシュテーブルを用いた以前の実施形態の話されています。
上記図の隣接テーブルを示す例示図である::
したがって、隣接リストは、単一の側鎖に保存されているすべてを指摘することです。
隣接リストを達成
実装隣接テーブルを使用することができる、多くのがあります二次元のベクトルエッジの各点を格納する(動的配列)。別の方法としては、使用することができますアナログ単一のリストの配列ここでの方法隣接テーブルを達成するために、単鎖アナログアレイを使用する方法を推奨し、その理由は、このように高効率であります。また、ハッシュテーブルと競合するこの解決策は、ジッパーと全く同じ方法です。唯一の違いは、我々は現在のポイントを格納するのに必要なエッジの長さを格納する必要がないので、その点に接続され、次に、ストレージ側です。
もう一つ:(スタティックネイバーテーブルチェーンもスターとして知られる前に)
int [] e = new int[N]; // 表示指向的点
int [] w = new int[N]; // 表示边长
int [] next = new int[N]; // next指针
int [] head = new int[N]; // 邻接表表头
int idx = 1; // 链表结点编号
// 插入
public static void add(int a, int b, int c){ // 将a和b之间建一条边
e[idx] = b; // 存储a点指向哪个点
w[idx] = c; // 存储边长
next[idx] = head[a];
head[a] = idx++;
}
// 遍历一个点的所有出边
for(int i = head[a]; i != 0; i = next[i]){
int b = e[i]; // a点指向的边
int c = w[i]; // a到b的边长
}
// 无向图的读入, 假如有m条边
for(int i = 0; i < m; i++){
int a = in.nextInt();
int b = in.nextInt();
int c = in.nextInt();
add(a, b, c);
add(b, a, c); //因为是无向图所以要反向建边。
}
アナログ隣接リストの配列で、それは、三つの主要な機能は、この章では難しいことではありません、完成学校を理解し、ほとんどの短絡を行くと学ぶことです:5つのアルゴリズムの最短経路問題