# WebGraph使用小结

WebGraph是一个非常不错的web图工具，网站地址http://webgraph.dsi.unimi.it/，提供多种图的格式，更可贵的是提供一种压缩图格式。

ImmutableGraph用来遍历，ASCIIGraph用来读取ASCIIGraph格式，ArrayListMutableGraph用来构建自己的web图，但是实现的不是很快捷，我自己实现了一个稍微改进的版本：

public class DictionaryMutableGraph:ImmutableGraph
{
protected List> graph = new List>();
protected int n;
protected long m;

public DictionaryMutableGraph(int numNodes, int[][] arc)
{
// scan
for (int i = arc.Length; i– != 0; )
{
if (arc[i].Length != 2) throw new ArgumentException(“The arc of index “ + i + “ has length “ + arc[i].Length);
if (arc[i][0] < 0 || arc[i][1] < 0 || arc[i][0] >= numNodes || arc[i][1] >= numNodes) throw new ArgumentException(“The arc of index “ + i + “ (“ + arc[i][0] + “, “ + arc[i][1] + “) is illegal“);
}

this.n = numNodes;
this.m = arc.LongLength;

for (int i = 0; i < numNodes; i++)
{
}

for (int i = 0; i < arc.Length; i++)

}

public void EnsureNode(int node)
{
if (node < 0)
throw new ArgumentException(“Illegal node index “ + node);
if (node >= n)
throw new ArgumentException(“Node index “ + node + “ is larger than graph order (“ + n + “)“);
}

{
for (int i = n - 1; i < n + numNodes; i++)
graph[i] = new HashSet();
n += numNodes;
}

public void RemoveNode(int node)
{
EnsureNode(node);
// remove node
graph.RemoveAt(node);
n–;

// remove arcs associate the node
for (int i = 0; i < n; i++)
{
List resize = new List();
int remove = -1;
foreach (int j in graph[i])
{
if (j == node)
{
remove = j;
}
else if(j > node)
{
}
}
if (remove != -1)
{
graph[i].Remove(remove);
m–;
}
foreach (int j in resize)
{
graph[i].Remove(j);
}
}
}

public void AddArc(int i, int j)
{
EnsureNode(i);
EnsureNode(j);
m++;
}

public void RemoveArc(int i, int j)
{
EnsureNode(i);
EnsureNode(j);
graph[i].Remove(j);
n–;
}

public override int[] successorArray(int x)
{
return graph[x].ToArray();
}

public override LazyIntIterator successors(int x)
{
return new DMGrapLazyIntIterator(this, x);
}

public override NodeIterator nodeIterator()
{
return new DMGraphNodeIterator(this);
}

public override NodeIterator nodeIterator(int from)
{
return new DMGraphNodeIterator(this, from);
}

public override ImmutableGraph copy()
{
return this;
}

public override int numNodes()
{
return n;
}

public override long numArcs()
{
return m;
}

public override int outdegree(int i)
{
EnsureNode(i);
return graph[i].Count;
}

public override bool randomAccess()
{
return true;
}

private class DMGraphNodeIterator : NodeIterator
{
DictionaryMutableGraph dmgraph;
int from;

public DMGraphNodeIterator(DictionaryMutableGraph dmgraph, int from)
{
this.dmgraph = dmgraph;
this.from = from - 1;
}

public DMGraphNodeIterator(DictionaryMutableGraph dmgraph):this(dmgraph, 0)
{
}

public override int outdegree()
{
return dmgraph.outdegree(from);
}

public override java.lang.Integer next()
{
return new java.lang.Integer(++from);
}

public override int nextInt()
{
return ++from;
}

public override void remove()
{
dmgraph.RemoveNode(from);
}

public override int skip(int n)
{
from += n;
return from;
}

public override int[] successorArray()
{
return dmgraph.successorArray(from);
}

public override LazyIntIterator successors()
{
return new DMGrapLazyIntIterator(dmgraph, from);
}

public override bool hasNext()
{
if (from < dmgraph.n - 1)
return true;
return false;
}
}

private class DMGrapLazyIntIterator : LazyIntIterator
{
private HashSet.Enumerator em;
public DMGrapLazyIntIterator(DictionaryMutableGraph dmgraph, int node)
{
em = dmgraph.graph[node].GetEnumerator();
}
public int nextInt()
{
if (em.MoveNext())
return em.Current;
else
return -1;
}

public int skip(int i)
{
bool next = false;
for (int j = 0; j < i; j++)
{
next = em.MoveNext();
}
if (next)
return em.Current;
return -1;
}
}
}