1. 程式人生 > >c++ 圖(鄰接表)

c++ 圖(鄰接表)

/*
連通鄰接表:
        由頂點表和邊表組成,頂點表中存著資料和指向邊表的指標
  邊表是一個鏈,存著頂點表的相關聯的資料在頂點表的位置與權值
下面就是建表 遍歷(深度優先DFS與廣度優先BFS)
*/

#include <iostream>
#define MAXSIZE 30
using namespace std;
typedef struct Sidetable                //邊表節點結構體 
{
 int DataPosition;
 int Weight;
 Sidetable* Next;
}Side_Table;
typedef struct Vertextable              //頂點表結構體
{
 char Data;
 Sidetable* Size_Headptr;
}Vertex_Table;
class Map                               //圖類
{
private:
 int Visited[MAXSIZE];
 int Nums;                           //實際資料個數
 Vertex_Table DataArry[MAXSIZE];     //物件陣列
public:
 Map()                                //初始化建構函式
 {
  Nums = 0;
  for(int i = 0; i <= MAXSIZE; i++)
  {
   DataArry[i].Data = '\0';              //初始化頂點表資料域
   DataArry[i].Size_Headptr = NULL;      //初始化頂點表指標域
   Visited[i] = 0;
  }
 }
 ~Map()                                        //解構函式,在沒寫解構函式的時候
 {                                             //程式雖然執行完了 但是終止了,記憶體錯誤,寫上解構函式就沒事了
              //看來解構函式還是必要的
  Side_Table* p;
  for(int i = 1; i <= Nums; i++)
  {
   p = DataArry[i].Size_Headptr;
   while(p)
   {
    DataArry[i].Size_Headptr = p->Next;
    delete p;
    p = DataArry[i].Size_Headptr;
   }
  }
 }
 void SetData();         //輸入資料
 int Re_Nums(){return Nums;}       
 void VisitedClear();
 void Set_Endgsrelationship();                   //設定頂點關係及建圖
 int Re_Position(char);                          //返回資料在物件陣列中的位置
 //***********遍歷函式 
 void DFSljb(int);                                  //深度優先搜尋
 void TheDFSljb();
 void BFSljb();                                    //廣度優先搜尋             
};
void Map::VisitedClear()
{
 for(int i = 0; i < MAXSIZE; i++)
 
 {
  Visited[i] = 0;
 }
}
void Map::SetData()
{
 int i = 1;
 while(cin>>DataArry[i].Data,DataArry[i].Data != '.')
 {
  i++;
  Nums++;
 }
}
int Map::Re_Position(char ch)
{
 int i = 1;
 while(i <= Nums)
 {
  if(DataArry[i].Data == ch)
  {
   break;
  }
  i++;
 }
 return i;
}
void Map::DFSljb(int i)
{
 Side_Table* p;
 cout<<DataArry[i].Data<<" ";
 Visited[i] = 1;
 p = DataArry[i].Size_Headptr;
 while(p != NULL)
 {
  if(Visited[p->DataPosition] == 0)
  {
   DFSljb(p->DataPosition);
   
  }
  p = p->Next;
 }
}
void Map::TheDFSljb()
{
 DFSljb(1);                 // 從第一個開始遍歷
}
void Map::Set_Endgsrelationship()
{
 int pos1,pos2,weight;                //pos為輸入資料在物件陣列中的位置
 char ch1,ch2;
 Side_Table* p;
 while(cin>>ch1>>ch2>>weight,ch1 != '.' && ch2 != '.')
 {
  pos1 = Re_Position(ch1);              //儲存字元位置
  pos2 = Re_Position(ch2);
  p = new Side_Table();                   
  p->DataPosition = pos2;
  p->Weight = weight;
  p->Next = DataArry[pos1].Size_Headptr;
  DataArry[pos1].Size_Headptr = p;

  p = new Side_Table();                   //因為建立的是無向圖,所以還要加成pos2-》pos1
  p->DataPosition = pos1;    //若要改成有向只要吧這四行去掉就行了
  p->Weight = weight;
  p->Next = DataArry[pos2].Size_Headptr;
  DataArry[pos2].Size_Headptr= p;
 }
}
void Map::BFSljb()
{
 VisitedClear();
 int i,queue[MAXSIZE],front = 0,rear = 0;
 Side_Table* p;
 cout<<DataArry[1].Data<<" ";                 //從1開始遍歷
 Visited[1] = 1;
 rear = rear + 1; 
 queue[rear] = 1;
                             //入隊
 while(front != rear)
 {
  front = front + 1;
  i = queue[front];                     //出隊
 
  p = DataArry[i].Size_Headptr;    
  while(p != NULL)
  {
   if(Visited[p->DataPosition] == 0)            // 如果為訪問
   {
    cout<<DataArry[p->DataPosition].Data<<" ";    //列印
    Visited[p->DataPosition] = 1;            //標記
    rear = rear + 1;                           
    queue[rear] = p->DataPosition;           //入隊
                                  //p指向另一相關聯頂點
   }
   p = p->Next;
  }
 }
 
}
int main()
{
 Map map1;
 cout<<"請輸入頂點資料(以'.'結束輸入):";
 map1.SetData();
 cout<<endl<<"您一共輸入了"<<map1.Re_Nums()<<"個數據."<<endl<<endl;
 cout<<"請輸入頂點關係及權值(以. . 結束輸入):"<<endl;
 map1.Set_Endgsrelationship();
 cout<<"深度優先搜尋遍歷圖為:";
 map1.TheDFSljb();cout<<endl;
 cout<<"廣度優先搜尋遍歷圖為:";
 map1.BFSljb();cout<<endl;
 return 0;
}
/*
a b 1
a c 2
c d 3
*/v