图的基本操作与实现

图的基本操作与实现

[问题描述]

自选存储结构,实现对图的操作。

[基本要求]

(1)自选存储结构,输入含n个顶点(用字符表示顶点)和e条边的图G;

(2)求每个顶点的度,输出结果;

(3)指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列(提示:使用一个栈实现DFS);

(4)指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列(提示:使用一个队列实现BFS);

(5)输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关联的边,并作DFS遍历(执行操作3);否则输出信息“无x”;

(6)判断图G是否是连通图,输出信息“YES”/“NO”;

(7)如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G, 然后再执行操作(2);反之亦然。

代码:选邻接矩阵作为存储结构

#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
queue<int>q;
class Graph
{
public:
    int n;
    char dot[10];
    int a[10][10];
    int visited[10];
public: 
    void ini();
    void degree(char);
    void del(char);
    void dfs(char,bool);
    void bfs(char);
    bool isConnected();
    void change();
    ~ Graph();
};
Graph::~ Graph(){
}

void Graph::ini(){
    memset(visited,0,sizeof(visited)); 
    memset(a,0,sizeof(a));
    int i, j, m, p, q;
    char x,y,z;
    cout<<"请输入图中点的个数:"<<endl;
    cin>>n;
    cout<<"请输入图的点集,以空格分开:"<<endl;
    for(j=0;j<n;j++)
        cin>>dot[j];
    cout<<"请输入图中边的个数:"<<endl;
    cin>>m;
    cout<<"请输入图的边集:"<<endl;
    for(i=0;i<m;i++){
          cin>>x>>y;
        for(p=0;p<n;p++)
            if(x==dot[p])
                break;
        for(q=0;q<n;q++)
            if(y==dot[q])
                break;
        if(p==n||q==n)     cout<<"输入错误!"<<endl;
        else a[p][q]=a[q][p]=1;    
    }
    for (i = 0;i < n;i++) {
        for (j = 0;j < n;j++)
            cout<<a[i][j]<<"  ";
        cout<<endl;
    }
}

void Graph::degree(char c){
    int i,j,deg=0;
    for(i=0;i<n;i++)
        if(dot[i]==c)
            break;
    for(j=0;j<n;j++)
        deg+=a[i][j];
    cout<<"定点"<<c<<"的度为:"<<deg<<endl; 
}

void Graph::dfs(char c,bool b){//递归实现
    if(b) 
        cout<<c<<" "; 
    int i,j;
    for(i=0;i<n;i++)
        if(dot[i]==c)
            break;
    visited[i]=1;
    for(int w=0;w<n;w++)
        if((a[i][w]!=0)&&(!visited[w]))
            dfs(dot[w],b);
}

void Graph::bfs(char c){//队列实现 
    cout<<c<<" "; 
    int i,u;
    for(i=0;i<n;i++)
        if(dot[i]==c)
            break;
    visited[i]=1;
    q.push(i);
    while(!q.empty()){
        u=q.front();
        q.pop();
        for(int w=0;w<n;w++)    
            if((a[u][w]!=0)&&(!visited[w])){
                cout<<dot[w]<<" ";
                visited[w]=1;
                q.push(w);
            }    
    }
}

void Graph::del(char ch){
    int i,j,k;
    for(i=0; i<n; i++)          ///遍历顶点数组
        if(ch==dot[i])
            break;
    if(i==n){
        cout<<"无"<<ch<<endl; //如果循环正常结束则i=g->vexnum,此时说明不存在该顶点
        return ;
    }
    else{
        for(j=0; j<n; j++)     ///如果存在,则将与顶点相关的边覆盖
            for(k=0; k<n; k++){
                if(j>=i&&k>=i)
                    a[j][k]=a[j+1][k+1];
                if(j>=i&&k<i)
                    a[j][k]=a[j+1][k];
                if(j<i&&k>=i)
                    a[j][k]=a[j][k+1];
            }
    }
    for(j=0; j<n; j++)         ///覆盖该顶点
        if(j>=i)
            dot[j]=dot[j+1];
    n--;
    cout<<"删除该顶点后剩余顶点为:\n";
    for(j=0; j<n; j++)
        cout<<dot[j]<<" ";
    cout<<endl;
    cout<<"删除后邻接矩阵为:\n";
    for(j=0; j<n; j++)
    {
        for(k=0; k<n; k++)
            cout<<a[j][k]<<" ";
        cout<<endl;
    }
    memset(visited,0,sizeof(visited)); 
    cout<<"从第一个顶点开始的DFS遍历为:";
    dfs(dot[0],true);
}

bool Graph::isConnected(){
    memset(visited,0,sizeof(visited)); 
    dfs(dot[0],false);
    for(int i=0;i<n;i++)    
        if(visited[i]==0){
            return false;
        }
    return true;
}

void Graph::change(){
    for(int i=0;i<n;i++){
        memset(visited,0,sizeof(visited)); 
        dfs(dot[i],true);
        cout<<endl;
    }
}

int main(){
    Graph graph; 
    graph.ini();
    for(int i=0;i<graph.n;i++)
        graph.degree(graph.dot[i]);
    char x;     
    cout<<"请输入深搜起点: ";
    cin>>x;
    graph.dfs(x,true);
    cout<<endl;
    memset(graph.visited,0,sizeof(graph.visited)); 
    cout<<"请输入广搜起点: ";
    cin>>x;
    graph.bfs(x);
    cout<<endl;
    cout<<"是否是连通图: ";
    if(graph.isConnected())
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;
    cout<<"请输入欲删除的顶点:";
    cin>>x; 
    graph.del(x);
    cout<<endl<<"转换成邻接表:"<<endl;;    
    graph.change();
    for(int i=0;i<graph.n;i++)
        graph.degree(graph.dot[i]);    
    return 0;
}

  • 7
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在月光下弹琴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值