用鄰接表解決圖的編程
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//鄰接矩陣結點
class AdjMatrixNode<T>
{
private T _Data;
public T Data
{
get { return _Data; }
set { _Data = value; }
}
public AdjMatrixNode(T data)
{
this._Data = data;
}
}
//圖的操作接口
interface IGraph<T>
{
void AddNode(int index, AdjMatrixNode<T> node);//在圖中新增加一個頂點
AdjMatrixNode<T> GetNode(int index);//獲取圖中的指定頂點
void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2);//在兩個頂點之間添加指定權值的邊或者弧
void SetEdge(int index1, int index2);
void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2, int index);
void DeleteEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2);
int GetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2);//獲取兩個頂點之間的邊
int GetEdge(int index1, int index2);
int GetNumOfVertex();//獲取鄰接矩陣定點數
int GetNumOfEdge();//獲取鄰接矩陣邊或弧的數目
int GetIndex(AdjMatrixNode<T> node);//獲取指定結點在圖中的序號
bool IsEdge(AdjMatrixNode<T> node1,AdjMatrixNode<T> node2);//判定兩個結點之間是否有邊
bool IsNode(AdjMatrixNode<T> node);//判定指定結點是否是圖的頂點
}
//無向圖鄰接表類
class GraphAdjList<T> : IGraph<T>
{
private AdjListNoVexNode<T>[] _AdjList;
public GraphAdjList(AdjMatrixNode<T>[] nodes)
{
this._AdjList = new AdjListNoVexNode<T>[nodes.Length];
for (int i = 0; i < nodes.Length; i++)
{
this._AdjList[i] = new AdjListNoVexNode<T>(nodes[i]);
}
}
//在圖中新增加一個頂點
public void AddNode(int index, AdjMatrixNode<T> node)
{
this._AdjList[index] = new AdjListNoVexNode<T>(node);
}
//獲取圖中的指定頂點
public AdjMatrixNode<T> GetNode(int index)
{
return this._AdjList[index].Data;
}
//在兩個頂點之間添加指定權值的邊或者弧
public void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
SetEdge(node1, node2, 1);
}
public void SetEdge(int index1, int index2)
{
SetEdge(GetNode(index1), GetNode(index2), 1);
}
public void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2, int info)
{
if (!IsNode(node1) || !IsNode(node2) || IsEdge(node1, node2))
{
Console.Write("Node is node belong to the graph or edge has existed !");
return;
}
if (info == 0)
{
return;
}
//處理node1的鄰接表
AdjListNode<T> p = new AdjListNode<T>(GetIndex(node2), info);
if (this._AdjList[GetIndex(node1)].FirstAdj == null)
{
//node1沒有鄰接頂點
this._AdjList[GetIndex(node1)].FirstAdj = p;
}
else
{
p.NextAdj = this._AdjList[GetIndex(node1)].FirstAdj;
this._AdjList[GetIndex(node1)].FirstAdj = p;
}
//處理node2的鄰接表
p = new AdjListNode<T>(GetIndex(node1), info);
if (this._AdjList[GetIndex(node2)].FirstAdj == null)
{
//node1沒有鄰接頂點
this._AdjList[GetIndex(node2)].FirstAdj = p;
}
else
{
p.NextAdj = this._AdjList[GetIndex(node2)].FirstAdj;
this._AdjList[GetIndex(node2)].FirstAdj = p;
}
}
public void DeleteEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
if (!IsNode(node1) || !IsNode(node2) || !IsEdge(node1, node2))
{
Console.Write("Node is node belong to the graph or edge is not exist !");
return;
}
AdjListNode<T> p = this._AdjList[GetIndex(node1)].FirstAdj;
AdjListNode<T> pre = null;
while (p.AdjVex != GetIndex(node2))
{
pre = p;
p = p.NextAdj;
}
pre.NextAdj = p.NextAdj;
p = this._AdjList[GetIndex(node2)].FirstAdj;
pre = null;
while (p.AdjVex != GetIndex(node1))
{
pre = p;
p = p.NextAdj;
}
pre.NextAdj = p.NextAdj;
}
//獲取兩個頂點之間的邊
public int GetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
if (!IsNode(node1) || !IsNode(node2))
{
Console.WriteLine("Node is not belong to graph !");
return 0;
}
AdjListNode<T> p = this._AdjList[GetIndex(node1)].FirstAdj;
while (p != null)
{
if (p.AdjVex == GetIndex(node2))
{
return p.Info;
}
p = p.NextAdj;
}
return 0;
}
public int GetEdge(int index1, int index2)
{
if (!IsNode(GetNode(index1)) || !IsNode(GetNode(index2)))
{
Console.WriteLine("Node is not exist !");
return 0;
}
return GetEdge(GetNode(index1), GetNode(index2));
}
//獲取鄰接矩陣定點數
public int GetNumOfVertex()
{
return this._AdjList.Length;
}
//獲取鄰接矩陣邊或弧的數目
public int GetNumOfEdge()
{
int NumOfEdge = 0;
foreach (AdjListNoVexNode<T> node in this._AdjList)
{
AdjListNode<T> p = node.FirstAdj;
while (p != null)
{
NumOfEdge++;
p = p.NextAdj;
}
}
return NumOfEdge / 2;
}
//獲取指定結點在圖中的序號
public int GetIndex(AdjMatrixNode<T> node)
{
for (int i = 0; i < this._AdjList.Length; i++)
{
if (this._AdjList[i].Data.Data.Equals(node.Data))
{
return i;
}
}
return -1;
}
//判定兩個結點之間是否有邊
public bool IsEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
if (!IsNode(node1) || !IsNode(node2))
{
Console.WriteLine("Node is not belong to graph !");
return false;
}
AdjListNode<T> p = this._AdjList[GetIndex(node1)].FirstAdj;
while (p != null)
{
if (p.AdjVex == GetIndex(node2))
{
return true;
}
p = p.NextAdj;
}
return false;
}
//判定指定結點是否是圖的頂點
public bool IsNode(AdjMatrixNode<T> node)
{
foreach (AdjListNoVexNode<T> nd in this._AdjList)
{
if (node.Equals(nd.Data))
{
return true;
}
}
return false;
}
}
#region 用鄰接表解決圖的編程
int maxNodes = 0;
AdjMatrixNode<string>[] nodes;
IGraph<string> g = null;
char ch;
do
{
Console.WriteLine();
Console.WriteLine("請輸入操作選項:");
Console.WriteLine("1.添加頂點");
Console.WriteLine("2.添加邊");
Console.WriteLine("3.添加鄰接表");
Console.WriteLine("4.退出");
ch = Convert.ToChar(Console.ReadLine());
switch (ch)
{
case '1':
Console.Write("高速公路城市網中的城市數:");
maxNodes = Convert.ToInt32(Console.ReadLine());
nodes = new AdjMatrixNode<string>[maxNodes];
for (int i = 0; i < maxNodes; i++)
{
Console.Write("請輸入城市:{0}", i + 1);
nodes[i] = new AdjMatrixNode<string>(Console.ReadLine());
}
g = new GraphAdjList<string>(nodes);
break;
case '2':
int info;
for (int i = 0; i < maxNodes; i++)
{
for (int j = i + 1; j < maxNodes; j++)
{
Console.Write("輸入{0}到{1}之間的距離", g.GetNode(i).Data, g.GetNode(j).Data);
info = Convert.ToInt32(Console.ReadLine());
g.SetEdge(g.GetNode(i), g.GetNode(j), info);
}
}
break;
case '3':
if (g.GetNumOfVertex() == 0)
{
Console.WriteLine("交通網未建 !");
return;
}
for (int i = 0; i < g.GetNumOfVertex(); i++)
{
Console.Write(g.GetNode(i).Data + "\t");
}
Console.WriteLine();
if (g.GetNumOfEdge() != 0)
{
for (int i = 0; i < g.GetNumOfEdge(); i++)
{
for (int j = i + 1; j < g.GetNumOfEdge(); j++)
{
if (g.GetEdge(i, j) != 0)
{
Console.Write("{0}->{1}:{2}\t", g.GetNode(i).Data, g.GetNode(j).Data, g.GetEdge(i, j) + "\t");
}
}
Console.WriteLine();
}
}
break;
}
} while (ch != 'y');
#endregion
class AdjMatrixNode<T>
{
private T _Data;
public T Data
{
get { return _Data; }
set { _Data = value; }
}
public AdjMatrixNode(T data)
{
this._Data = data;
}
}
//圖的操作接口
interface IGraph<T>
{
void AddNode(int index, AdjMatrixNode<T> node);//在圖中新增加一個頂點
AdjMatrixNode<T> GetNode(int index);//獲取圖中的指定頂點
void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2);//在兩個頂點之間添加指定權值的邊或者弧
void SetEdge(int index1, int index2);
void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2, int index);
void DeleteEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2);
int GetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2);//獲取兩個頂點之間的邊
int GetEdge(int index1, int index2);
int GetNumOfVertex();//獲取鄰接矩陣定點數
int GetNumOfEdge();//獲取鄰接矩陣邊或弧的數目
int GetIndex(AdjMatrixNode<T> node);//獲取指定結點在圖中的序號
bool IsEdge(AdjMatrixNode<T> node1,AdjMatrixNode<T> node2);//判定兩個結點之間是否有邊
bool IsNode(AdjMatrixNode<T> node);//判定指定結點是否是圖的頂點
}
//無向圖鄰接表類
class GraphAdjList<T> : IGraph<T>
{
private AdjListNoVexNode<T>[] _AdjList;
public GraphAdjList(AdjMatrixNode<T>[] nodes)
{
this._AdjList = new AdjListNoVexNode<T>[nodes.Length];
for (int i = 0; i < nodes.Length; i++)
{
this._AdjList[i] = new AdjListNoVexNode<T>(nodes[i]);
}
}
//在圖中新增加一個頂點
public void AddNode(int index, AdjMatrixNode<T> node)
{
this._AdjList[index] = new AdjListNoVexNode<T>(node);
}
//獲取圖中的指定頂點
public AdjMatrixNode<T> GetNode(int index)
{
return this._AdjList[index].Data;
}
//在兩個頂點之間添加指定權值的邊或者弧
public void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
SetEdge(node1, node2, 1);
}
public void SetEdge(int index1, int index2)
{
SetEdge(GetNode(index1), GetNode(index2), 1);
}
public void SetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2, int info)
{
if (!IsNode(node1) || !IsNode(node2) || IsEdge(node1, node2))
{
Console.Write("Node is node belong to the graph or edge has existed !");
return;
}
if (info == 0)
{
return;
}
//處理node1的鄰接表
AdjListNode<T> p = new AdjListNode<T>(GetIndex(node2), info);
if (this._AdjList[GetIndex(node1)].FirstAdj == null)
{
//node1沒有鄰接頂點
this._AdjList[GetIndex(node1)].FirstAdj = p;
}
else
{
p.NextAdj = this._AdjList[GetIndex(node1)].FirstAdj;
this._AdjList[GetIndex(node1)].FirstAdj = p;
}
//處理node2的鄰接表
p = new AdjListNode<T>(GetIndex(node1), info);
if (this._AdjList[GetIndex(node2)].FirstAdj == null)
{
//node1沒有鄰接頂點
this._AdjList[GetIndex(node2)].FirstAdj = p;
}
else
{
p.NextAdj = this._AdjList[GetIndex(node2)].FirstAdj;
this._AdjList[GetIndex(node2)].FirstAdj = p;
}
}
public void DeleteEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
if (!IsNode(node1) || !IsNode(node2) || !IsEdge(node1, node2))
{
Console.Write("Node is node belong to the graph or edge is not exist !");
return;
}
AdjListNode<T> p = this._AdjList[GetIndex(node1)].FirstAdj;
AdjListNode<T> pre = null;
while (p.AdjVex != GetIndex(node2))
{
pre = p;
p = p.NextAdj;
}
pre.NextAdj = p.NextAdj;
p = this._AdjList[GetIndex(node2)].FirstAdj;
pre = null;
while (p.AdjVex != GetIndex(node1))
{
pre = p;
p = p.NextAdj;
}
pre.NextAdj = p.NextAdj;
}
//獲取兩個頂點之間的邊
public int GetEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
if (!IsNode(node1) || !IsNode(node2))
{
Console.WriteLine("Node is not belong to graph !");
return 0;
}
AdjListNode<T> p = this._AdjList[GetIndex(node1)].FirstAdj;
while (p != null)
{
if (p.AdjVex == GetIndex(node2))
{
return p.Info;
}
p = p.NextAdj;
}
return 0;
}
public int GetEdge(int index1, int index2)
{
if (!IsNode(GetNode(index1)) || !IsNode(GetNode(index2)))
{
Console.WriteLine("Node is not exist !");
return 0;
}
return GetEdge(GetNode(index1), GetNode(index2));
}
//獲取鄰接矩陣定點數
public int GetNumOfVertex()
{
return this._AdjList.Length;
}
//獲取鄰接矩陣邊或弧的數目
public int GetNumOfEdge()
{
int NumOfEdge = 0;
foreach (AdjListNoVexNode<T> node in this._AdjList)
{
AdjListNode<T> p = node.FirstAdj;
while (p != null)
{
NumOfEdge++;
p = p.NextAdj;
}
}
return NumOfEdge / 2;
}
//獲取指定結點在圖中的序號
public int GetIndex(AdjMatrixNode<T> node)
{
for (int i = 0; i < this._AdjList.Length; i++)
{
if (this._AdjList[i].Data.Data.Equals(node.Data))
{
return i;
}
}
return -1;
}
//判定兩個結點之間是否有邊
public bool IsEdge(AdjMatrixNode<T> node1, AdjMatrixNode<T> node2)
{
if (!IsNode(node1) || !IsNode(node2))
{
Console.WriteLine("Node is not belong to graph !");
return false;
}
AdjListNode<T> p = this._AdjList[GetIndex(node1)].FirstAdj;
while (p != null)
{
if (p.AdjVex == GetIndex(node2))
{
return true;
}
p = p.NextAdj;
}
return false;
}
//判定指定結點是否是圖的頂點
public bool IsNode(AdjMatrixNode<T> node)
{
foreach (AdjListNoVexNode<T> nd in this._AdjList)
{
if (node.Equals(nd.Data))
{
return true;
}
}
return false;
}
}
#region 用鄰接表解決圖的編程
int maxNodes = 0;
AdjMatrixNode<string>[] nodes;
IGraph<string> g = null;
char ch;
do
{
Console.WriteLine();
Console.WriteLine("請輸入操作選項:");
Console.WriteLine("1.添加頂點");
Console.WriteLine("2.添加邊");
Console.WriteLine("3.添加鄰接表");
Console.WriteLine("4.退出");
ch = Convert.ToChar(Console.ReadLine());
switch (ch)
{
case '1':
Console.Write("高速公路城市網中的城市數:");
maxNodes = Convert.ToInt32(Console.ReadLine());
nodes = new AdjMatrixNode<string>[maxNodes];
for (int i = 0; i < maxNodes; i++)
{
Console.Write("請輸入城市:{0}", i + 1);
nodes[i] = new AdjMatrixNode<string>(Console.ReadLine());
}
g = new GraphAdjList<string>(nodes);
break;
case '2':
int info;
for (int i = 0; i < maxNodes; i++)
{
for (int j = i + 1; j < maxNodes; j++)
{
Console.Write("輸入{0}到{1}之間的距離", g.GetNode(i).Data, g.GetNode(j).Data);
info = Convert.ToInt32(Console.ReadLine());
g.SetEdge(g.GetNode(i), g.GetNode(j), info);
}
}
break;
case '3':
if (g.GetNumOfVertex() == 0)
{
Console.WriteLine("交通網未建 !");
return;
}
for (int i = 0; i < g.GetNumOfVertex(); i++)
{
Console.Write(g.GetNode(i).Data + "\t");
}
Console.WriteLine();
if (g.GetNumOfEdge() != 0)
{
for (int i = 0; i < g.GetNumOfEdge(); i++)
{
for (int j = i + 1; j < g.GetNumOfEdge(); j++)
{
if (g.GetEdge(i, j) != 0)
{
Console.Write("{0}->{1}:{2}\t", g.GetNode(i).Data, g.GetNode(j).Data, g.GetEdge(i, j) + "\t");
}
}
Console.WriteLine();
}
}
break;
}
} while (ch != 'y');
#endregion