C++鄰接表與無向圖

C++鄰接表與無向圖

參考《算法》,採用鄰接表實現圖結構,實現DFS以及BFS等算法。具體原理參考書本,此處給出C++版本實現。

#include<iostream>
#include<queue>
#include<algorithm>
#include<map>

using namespace std;

/*
 頂點       中間節點
 VNode     ENode
 0 | A --> 2(C) 1(B)
 1 | B --> 4(E) 3(D) 0(A)
 2 | C --> 6(G) 5(F) 0(A)
 3 | D --> 7(H) 1(B)
 4 | E --> 7(H) 1(B)
 5 | F --> 6(G) 2(C)
 6 | G --> 5(F) 2(C)
 7 | H --> 4(E) 3(D)
 */

const int MAX = 20;

struct ENode      //鄰接表的中間節點
{
    int adjvex;   //對應索引
    ENode* next;
};

typedef struct VNode //鄰接表頂點
{
    char vertex;     //值
    ENode* firstarc; //指向第一個中間節點
}AdjList[MAX];

class ALGraph         //圖
{
private:
    AdjList adjList;          //鄰接表數組
    int vexNum;              //節點數量
    int arcNum;              //連邊數量
    bool visited[MAX];        //標記被訪問
    map<int,int> unionfield;  //標記節點屬於哪個連通域

public:
    void CreateGraph();       //創建圖
    void PrintGraph();        //打印圖
    void DFS(int v,int field); //深度優先搜索
    void BFS();               //廣度優先搜索
    int DFS_findUnion();      //深度優先搜索尋找連通域
    bool isConnect(int m,int n); //判斷兩個節點是否連通
};

void ALGraph::CreateGraph()
{
    cout << "請輸入圖的頂點數:" << endl;
    cin >> this->vexNum;
    cout << "請輸入圖的弧數:" << endl;
    cin >> this->arcNum;
    cout << "請輸入頂點信息:" << endl;
    for (int i = 0; i<this->vexNum; i++)  //構建頂點數組
    {
        cin >> this->adjList[i].vertex;
        this->adjList[i].firstarc = nullptr;
    }
    cout << "請輸入" << this->arcNum << "個弧的信息:" << endl;
    for (int i = 0; i<this->arcNum; i++)  //構建每條鄰接表
    {
        int h1, h2;
        cin >> h1 >> h2;
        ENode* temp = new ENode();
        temp->adjvex = h2;
        temp->next = this->adjList[h1].firstarc;
        this->adjList[h1].firstarc = temp;

        temp = new ENode();
        temp->adjvex = h1;
        temp->next = this->adjList[h2].firstarc;
        this->adjList[h2].firstarc = temp;
    }
}
void ALGraph::PrintGraph()
{
    for (int i = 0; i<this->vexNum; i++)
    {
        cout << this->adjList[i].vertex << "--------->";
        ENode* p = this->adjList[i].firstarc;
        while (p)
        {
            cout << this->adjList[p->adjvex].vertex << " ";
            p = p->next;
        }
        cout << endl;
    }
}
void ALGraph::BFS()
{
    for(int i=0;i<this->vexNum;i++)
    {
        visited[i] = false;
    }
    queue<int> q;
    for(int i=0;i<this->vexNum;i++)
    {
        if(!visited[i])
        {
            visited[i] = true;
            q.push(i);
            cout<<this->adjList[i].vertex<<" ";
            while(!q.empty())
            {
                int x = q.front();
                q.pop();
                ENode* p = this->adjList[x].firstarc;
                while(p)
                {
                    if(!visited[p->adjvex])
                    {
                        visited[p->adjvex] = true;
                        cout<<this->adjList[p->adjvex].vertex<<" ";
                        q.push(p->adjvex);
                    }
                    p = p->next;
                }
            }
        }
    }
}
void ALGraph::DFS(int v,int field)
{
    visited[v] = true;
    this->unionfield.insert(make_pair(v, field));
    cout << this->adjList[v].vertex << " ";

    ENode* p = this->adjList[v].firstarc;
    while (p)
    {
        if (!visited[p->adjvex])
            DFS(p->adjvex,field);
        p = p->next;
    }
}

int ALGraph::DFS_findUnion()
{
    this->unionfield.clear();
    int count = 0;                //連通域個數
    for(int i=0;i<this->vexNum;i++)
    {
        visited[i] = false;
    }
    cout<<"各個連通域如下所示:"<<endl;
    for(int i=0;i<this->vexNum;i++)
    {
        if(!visited[i])
        {
            DFS(i,++count);
            cout<<endl;
        }

    }
    cout<<endl;
    return count;
}
bool ALGraph::isConnect(int m,int n)
{
    return (this->unionfield[m]==this->unionfield[n])?true:false;
}


int main()
{
    ALGraph* graph = new ALGraph();
    graph->CreateGraph();
    cout<<graph->DFS_findUnion()<<"個連通域"<<endl;
    cout<<"連通情況爲:"<<graph->isConnect(6, 7)<<endl;
    return 0;
}
發佈了47 篇原創文章 · 獲贊 32 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章