BUCT数据结构——图

问题 A: 将邻接矩阵存储的图转换为邻接表存储的图

#include<bits/stdc++.h>
using namespace std;

#define MAX_SIZE 100

// 邻接矩阵存储的图
struct Graph{
    int vexNumber;
    string info[MAX_SIZE];
    int adjMatrix[MAX_SIZE][MAX_SIZE];
    Graph(){
        vexNumber=0;
        memset(adjMatrix,0,sizeof(adjMatrix));
    }
};

// 弧结点定义
struct ArcNode
{
    int weight; // 弧上的信息部分
    int adj;        // 邻接点的序号
    ArcNode *nextarc;
    ArcNode(){
        nextarc=NULL;
    }
};


// 顶点结点定义,也就是头节点定义 
struct VexNode
{
    string Info;        // 顶点上的信息部分
    ArcNode *firstarc;  // 弧链头指针
    VexNode(){
        firstarc=NULL;
        Info.clear();
    }
};

// 邻接表结构的图的定义
struct linkGraph
{
    VexNode *vexes;
    int vexnumber;
    linkGraph(){
        vexes=NULL;
    }
};

int InitGraph(linkGraph &G, int vexnumber)
{
    G.vexes = new VexNode[vexnumber];
    G.vexnumber = vexnumber;
    for (int i = 0; i < vexnumber; i++)
        G.vexes[i].firstarc = NULL;
    return 0;
}

// 将邻接矩阵存储的图转换为邻接表存储的图
void InitGraph(linkGraph &G, const Graph& g){
    int n=g.vexNumber;
    InitGraph(G,g.vexNumber);
    // cout<<G.vexnumber<<endl;
    for( int i=0;i<n;i++){
        G.vexes[i].Info=(char)(i+'a');
        for( int j=0;j<n;j++){
            if(g.adjMatrix[i][j]){
                ArcNode * NewNode=new ArcNode;
                NewNode->nextarc= G.vexes[i].firstarc;
                G.vexes[i].firstarc=NewNode;
                NewNode->weight=j;
            }
        }
    }
}

int DestroyGraph(linkGraph &G)
{
    for (int i = 0; i < G.vexnumber; i++)
    {
        while (G.vexes[i].firstarc != NULL)
        {
            ArcNode *p = G.vexes[i].firstarc;
            G.vexes[i].firstarc = p->nextarc;
            delete p;
        }
    }
    delete[]G.vexes;
    G.vexes = NULL;
    G.vexnumber = 0;
    return 0;
}


// 输出邻接表存储的图
void PrintGraph(const linkGraph& G){
    int n=G.vexnumber;
    for( int i=0;i<n;i++){
        cout<<G.vexes[i].Info;
        ArcNode *p=G.vexes[i].firstarc;
        while(p!=NULL){
            printf(" --> %c",p->weight+'a');
            p=p->nextarc;
        }
        cout<<endl;
    }
    return ;
}
// please comment the following code when you submit to OJ
int main(){
    //freopen("/config/workspace/answer/test.in","r",stdin);
    //freopen("/config/workspace/answer/test.out","w",stdout);
    Graph g;
    cin >> g.vexNumber;
    for(int i=0;i<g.vexNumber;i++){
        g.info[i] = (char)('a'+i);
        for(int j=0;j<g.vexNumber;j++){
            cin >> g.adjMatrix[i][j];
        }
    }
    linkGraph G;
    InitGraph(G,g);
    PrintGraph(G);
    DestroyGraph(G);
    return 0;
}

问题 B: 邻接表存储的图转化为邻接矩阵存储的图

#include<bits/stdc++.h>
using namespace std;

#define MAX_SIZE 100

// 邻接矩阵存储的图
struct Graph
{
    int vexNumber;
    string vexInfo[MAX_SIZE];
    int adjMatrix[MAX_SIZE][MAX_SIZE];
};

// 弧结点定义
struct ArcNode
{
    int weight;       // 弧上的信息部分
    int adj;          // 邻接点的序号
    ArcNode *nextarc; // 下一条边
    ArcNode(){
        nextarc =NULL;
    }
};

// 顶点结点定义
struct VexNode
{
    string Info;       // 顶点上的信息部分
    ArcNode *firstarc; // 弧链头指针
    VexNode(){
        firstarc=NULL;
    }
};

// 邻接表结构的图的定义
struct linkGraph
{
    VexNode *vexes; //  每个节点的邻接表
    int vexnumber;  //  节点数量
};

// 邻接表存储的图的初始化
int InitGraph(linkGraph &G, int vexnumber)
{
    G.vexes = new VexNode[vexnumber];
    G.vexnumber = vexnumber;
    for (int i = 0; i < vexnumber; i++)
        G.vexes[i].firstarc = NULL;
    return 0;
}

// 构造边节点指针
// ArcNode* getArcNode(int adj){
//     ArcNode* node = new ArcNode();
//     node->adj = adj;
//     node->nextarc = NULL;
//     return node;
// }

// 根据输入构造邻接表存储的图
void InputlinkGraph(linkGraph& LG){
    int n;
    cin>>n;
    InitGraph(LG,n);
    for( int i=0;i<n;i++){
        string s;
        cin>>s;
        int head=s[0]-'a';
        LG.vexes[head].Info=s[0];
        for( int j=s.size()-1;j>=2;j-=2){
            ArcNode * NewNode=new ArcNode;
            NewNode->weight=s[j]-'a';
            NewNode->nextarc=LG.vexes[head].firstarc;
            LG.vexes[head].firstarc=NewNode;
        }
    }
    return ;
}
// 将邻接表存储的图转化为邻接矩阵存储的图
void linkGraph2Graph(const linkGraph& LG, Graph& G){
    memset(G.adjMatrix,0,sizeof G.adjMatrix);
    int n=LG.vexnumber;
    G.vexNumber=n;
    for( int i=0;i<n;i++){
        ArcNode * p=LG.vexes[i].firstarc;
        while(p!=NULL){
            int j=p->weight;
            G.adjMatrix[i][j]=1;
            p=p->nextarc;
        }
    }
    return ;
}

// 输出邻接矩阵
void printGraph(const Graph& G){
    int n=G.vexNumber;
   for( int i=0;i<n;i++){
       for( int j=0;j<n;j++){
           cout<<G.adjMatrix[i][j]<<" ";
       }
       cout<<endl;
   }
}

void PrintlinkGraph(const linkGraph &LG){
    int n=LG.vexnumber;
    for( int i=0;i<n;i++){
        cout<<LG.vexes[i].Info;
        ArcNode *p=LG.vexes[i].firstarc;
        while(p!=NULL){
            printf(" --> %c",p->weight+'a');
            p=p->nextarc;
        }
        cout<<endl;
    }
}

// 邻接表存储的图的销毁
int DestroylinkGraph(linkGraph &G)
{
    for (int i = 0; i < G.vexnumber; i++)
    {
        while (G.vexes[i].firstarc != NULL)
        {
            ArcNode *p = G.vexes[i].firstarc;
            G.vexes[i].firstarc = p->nextarc;
            delete p;
        }
    }
    delete[] G.vexes;
    G.vexes = NULL;
    G.vexnumber = 0;
    return 0;
}
// please comment the following code when you submit to OJ
int main(){
    // freopen("/config/workspace/answer/test.in","r",stdin);
    linkGraph LG;
    Graph G;
    InputlinkGraph(LG);
    PrintlinkGraph(LG);
    linkGraph2Graph(LG,G);
    printGraph(G);
    DestroylinkGraph(LG);
    return 0;
}

问题 C: 邻接矩阵存储图的DFS

#include<bits/stdc++.h>
using namespace std;

#define MAX_SIZE 100

// 邻接矩阵存储的图
struct Graph
{
    int vexNumber;
    string vexInfo[MAX_SIZE];
    int adjMatrix[MAX_SIZE][MAX_SIZE];
};

// 查找v0的未被访问的邻接点
// int findAdjVex(const Graph& G, int v0, int visited[]){

// }
// 以顶点v0为起点,进行一趟DFS
void DFS(const Graph& G, int v0, int visited[]){
    // 第一步: 先访问v0,标记已访问
    visited[v0]=1;
    cout<<v0<<" ";
    // 第二步: 再对v0的所有未被访问的邻接点进行DFS
    for( int i=0;i<G.vexNumber;i++){
        if(G.adjMatrix[v0][i]==1&&visited[i]==0){
            DFS(G,i,visited);
        }
    }
}
// 对整个图进行DFS
void DFS(const Graph& G){
    // 第一步:初始化visited数组
    int visited[MAX_SIZE]={};
    // 第二步:以每个未被遍历的顶点为起点,进行DFS
    for( int i=0;i<G.vexNumber;i++){
        if(visited[i]==0) DFS(G,i,visited);
    }
    
}

// please comment the following code when you submit to OJ
int main(){
    // freopen("/config/workspace/answer/test.in","r",stdin);
    // freopen("/config/workspace/answer/test.out","w",stdout);
    
    Graph G;
    cin >> G.vexNumber;
    for(int i=0;i<G.vexNumber;i++){
        //我的编译器to_string没法用
        G.vexInfo[i] = (char)(i+'a');
        for(int j=0;j<G.vexNumber;j++){
            cin >> G.adjMatrix[i][j];
        }
    }
    DFS(G);
    return 0;
}

问题 D: 邻接矩阵存储图的DFS-非递归算法

#include <iostream>
#include <string>
#include <cstdio>
#include <stack>
#include <queue>
using namespace std;

#define MAX_SIZE 100

// 邻接矩阵存储的图
struct Graph
{
    int vexNumber;
    string vexInfo[MAX_SIZE];
    int adjMatrix[MAX_SIZE][MAX_SIZE];
};

// 查找v0的未被访问的邻接点
int findAdjVex(const Graph& G, int v0, int visited[]){
    for( int i=0;i<G.vexNumber;i++){
        if(G.adjMatrix[v0][i]==1&&visited[i]==0) return i; 
    }
    return -1;
}
// 以顶点v0为起点,进行一趟DFS
string DFS(const Graph& G, int v0, int visited[]){
    string result = "";
    stack<int>st;
    st.push(v0);
    result+=to_string(v0);
    result+=" ";
    visited[v0]=1;
    while(!st.empty()){
        int now=st.top();
        int to=findAdjVex(G,now,visited);
        if(to==-1) {
            st.pop();
            continue;
        }
        else {
            st.push(to);
            visited[to]=1;
            result+=to_string(to);
            result+=" ";
        }
    }
    return result;
}
// 对整个图进行DFS
string DFS(const Graph& G){
    string result = "";
    // 第一步:初始化visited数组
    const int n=G.vexNumber;
    int visited[MAX_SIZE]={};
    // 第二步:以每个未被遍历的顶点为起点,进行DFS
    for( int i=0;i<n;i++){
        if(visited[i]==0) result+= DFS(G,i,visited);
    }
    return result;
}

// please comment the following code when you submit to OJ
int main(){
    // freopen("/config/workspace/answer/test.in","r",stdin);
    // freopen("/config/workspace/answer/test.out","w",stdout);
    
    Graph G;
    cin >> G.vexNumber;
    for(int i=0;i<G.vexNumber;i++){
        G.vexInfo[i] = (char)(i+'a');
        for(int j=0;j<G.vexNumber;j++){
            cin >> G.adjMatrix[i][j];
        }
    }
    string str = DFS(G);
    cout << str << endl;
    return 0;
}


问题 E: 邻接矩阵存储图的BFS

#include<bits/stdc++.h>
using namespace std;
int m[110][110];
void bfs(int n){
    int vis[110]={};
    queue<int>q;
    for( int i=1;i<=n;i++){
        if(!vis[i]) q.push(i);
        else continue;
        while(!q.empty()){
            int now=q.front();
            q.pop();
            if(vis[now]) continue;
            vis[now]=1;
            cout<<now-1<<" ";
            for( int j=1;j<=n;j++){
                if(!vis[j]&&m[now][j]){
                    q.push(j);
                }
            }
        }
    }
}
int main(){
    int n;
    cin>>n;
    for( int i=1;i<=n;i++){
        for( int j=1;j<=n;j++){
            cin>>m[i][j];
        }
    }
    bfs(n);
}

问题 F: 案例6-1.2:邻接表存储图的广度优先遍历

#include<bits/stdc++.h>
using namespace std;
vector<int>h[100100];
int vis[100100];
void bfs( int x){
    queue<int>q;
    q.push(x);
    while(!q.empty()){
        int now=q.front();
        q.pop();
        if(vis[now]==1) continue;
        vis[now]=1;
        cout<<now<<" ";
        for( int i=0;i<h[now].size();i++){
            int to=h[now][i];
            if(vis[to]) continue;
            else q.push(to);
        }
    }
}
int main(){
    int n,m,x;
    cin>>n>>m>>x;
    for( int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        h[a].push_back(b);
        h[b].push_back(a);
    }
    for( int i=0;i<n;i++) sort(h[i].begin(),h[i].end());
    bfs(x);
}

问题 G: 邻接矩阵存储图的DFS完成序求解

#include <iostream>
#include <string>
#include <cstdio>
#include <stack>
#include <queue>
using namespace std;

#define MAX_SIZE 100

// 邻接矩阵存储的图
struct Graph
{
    int vexNumber;
    string vexInfo[MAX_SIZE];
    int adjMatrix[MAX_SIZE][MAX_SIZE];
};

// 查找v0的未被访问的邻接点
int findAdjVex(const Graph& G, int v0, int visited[]){
    for( int i=0;i<G.vexNumber;i++){
        if(G.adjMatrix[v0][i]==1&&visited[i]==0) return i; 
    }
    return -1;
}

// 算法7-1: 以某个节点为起点求解DFS完成序的算法 (邻接矩阵)
string DFS_finished(const Graph &G, int v0, int visited[]){
    string res="";
    visited[v0]=1;
    while(findAdjVex(G,v0,visited)!=-1){
        res+=DFS_finished(G,findAdjVex(G,v0,visited),visited);
    }
    res+=(char)(v0+'a');  
    return res;
}

// 算法7: DFS完成序的求解算法-邻接矩阵
string DFS_finished(const Graph &G){
    string res="";
    int n=G.vexNumber;
    int visited[MAX_SIZE]={};
    for( int i=0;i<n;i++){
        if(visited[i]==0) res+=DFS_finished(G,i,visited);
    }
    return res;
}
// please comment the following code when you submit to OJ
int main(){
    // freopen("/config/workspace/answer/test.in","r",stdin);
    // freopen("/config/workspace/answer/test.out","w",stdout);
    
    Graph G;
    cin >> G.vexNumber;
    for(int i=0;i<G.vexNumber;i++){
        G.vexInfo[i] = (char)('a'+ i);
        for(int j=0;j<G.vexNumber;j++){
            cin >> G.adjMatrix[i][j];
        }
    }
    string str = DFS_finished(G);
    cout << str << endl;
    return 0;
}

问题 H: 算法7-7,7-8:无向图的连通分量和生成树

#include<bits/stdc++.h>
using namespace std;
int m[100][100];
int vis[100];
int n;
string dfs( int x){
    string res="";
    res+=to_string(x);
    res+=" ";
    vis[x]=1;
    for( int i=0;i<n;i++){
        if(vis[i]==0&&m[x][i]==1){
            res+=dfs(i);
        }
    }
    return res;
}
int main(){
    cin>>n;
    for( int i=0;i<n;i++){
        for( int j=0;j<n;j++){
            cin>>m[i][j];
        }
    }
    for( int i=0;i<n;i++){
        if(vis[i]==0){
            cout<<dfs(i)<<endl;
        }
    }
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值