用鄰接表解決圖的編程

代码
 //鄰接矩陣結點
    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

 

posted @ 2009-12-29 11:42  samyangvs05  阅读(223)  评论(0编辑  收藏  举报