《数据结构》实验三报告(无向图邻接表的构造)

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e3;
typedef int LL;
typedef struct LNode* ToNode;
typedef struct Graph* ToGraph;
typedef struct LNode{///单链表
    LL num;///顶点编号
    LL val;///表头节点到直连点的边权
    LL indegree;///表头节点存下该点的入度
    LL outdegree;///表头节点存下该点的出度
    ToNode Next;
}LNode;
typedef struct Graph{
    ToNode A[maxn];
    LL graphnodes;///图的顶点数
    LL graphedges;///图的边数
}Graph;
void addnode(ToGraph &G,LL v1,LL v2){
    ToNode p=(ToNode)malloc(sizeof(LNode));
    p=(G->A[v1]);
    while( p->Next!=nullptr ){
        p=p->Next;
        if(p->num==v2) return;
        if(p==nullptr) break;
    }
    ToNode k=(ToNode)malloc(sizeof(LNode));
    p->Next=k;
    k->num=v2;
    k->Next=nullptr;
    return;
}
void find(ToGraph &G,LL v1,LL v2){
        if(G->A[v1]->num==v1){
            addnode(G,v1,v2);
            cout<<"找到"<<v1<<"顶点"<<endl;
            G->A[v1]->outdegree++;///该点出度++
        }
        if(G->A[v2]->num==v2){

            G->A[v2]->indegree++;///该点入读++
            cout<<(G->A[v2]->indegree)<<endl;
        }
}
void CreateGraph(ToGraph& G,LL op){
    G=(ToGraph)malloc(sizeof(Graph));
    if(op==0) cout<<"要构建的无向图的顶点数目:"<<endl;
    else if(op==1) cout<<"要构建的有向图的点数目:"<<endl;
    cin>>(G->graphnodes);
    if(op==0) cout<<"要构建的无向图的边的数目:"<<endl;
    else if(op==1) cout<<"要构建的有向图的边数目:"<<endl;
    cin>>(G->graphedges);
    for(LL i=1;i<=(G->graphnodes);i++){
        LL v;
        cout<<"顶点为:";cin>>v;
        G->A[v]=(ToNode)malloc(sizeof(LNode));
        G->A[v]->num=v;
        G->A[v]->indegree=0;
        G->A[v]->outdegree=0;
        G->A[v]->Next=nullptr;
    }
    for(LL i=1;i<=(G->graphedges);i++){
        cout<<"请输入边(vi,vj)上的顶点信息"<<endl;
        LL v1,v2;///v1<---->v2
        cin>>v1>>v2;
        if(op==0){
            find(G,v1,v2);
            find(G,v2,v1);
        }
        else if(op==1){
            find(G,v1,v2);
        }
    }
}
LL findnum(ToGraph& G,LL v){
    for(LL i=1;i<=G->graphnodes;i++){
        if(G->A[i]->num==v) return i;
    }
    return 0;
}
void showGraph(ToGraph& G){
    cout<<"所建立的邻接表如下:"<<endl;
    for(LL i=1;i<=G->graphnodes;i++){
        ///LL v=findnum(G,i);///找标号为i的点
        cout<<"标号为"<<i<<"的点:";
        ToNode p=G->A[i];
        if(p->Next==nullptr){
            cout<<"该点没有相连点";
        }
        else{
            while(p->Next!=nullptr){
                p=p->Next;
                cout<<" "<<p->num<<" ";
            }
        }
        cout<<endl;
    }
}
bool checkedge(ToGraph& G){
    LL v1,v2;
    cout<<"输入边的端点v1:";cin>>v1;
    cout<<"输入边的端点v2:";cin>>v2;
    ToNode p=G->A[v1];
    if(p->Next==nullptr) return 0;
    while(p->Next!=nullptr){
        p=p->Next;
        if(p->num==v2) return 1;
    }
    return 0;
}
void caldegree(ToGraph& G,LL op){///计算入度和出度
     if(op==1){
        for(LL i=1;i<=G->graphnodes;i++){
            cout<<"起点为"<<i<<":";
            cout<<"该点"<<i<<"的入度为:"<<G->A[i]->indegree<<endl;
            cout<<"该点"<<i<<"的出度为:"<<G->A[i]->outdegree<<endl;
            cout<<endl;
        }
     }
     else{
         for(LL i=1;i<=G->graphnodes;i++){
            cout<<"起点为"<<i<<":";
            cout<<"该点"<<i<<"的度数为:"<<G->A[i]->indegree<<endl;
            cout<<endl;
        }
     }
}
int main(void)
{
  ///cin.tie(0);std::ios::sync_with_stdio(false);
  ToGraph G;
  cout<<"选择构建无向图(输入0)or有向图(输入1)"<<endl;
  LL op;cin>>op;
  if(op==0){
    CreateGraph(G,0);///无向图
  }
  else if(op==1){
    CreateGraph(G,1);///有向图
  }
  showGraph(G);
  cout<<"判断边是否存在"<<endl;
  if(checkedge(G)){
    cout<<"该边存在"<<endl;
  }
  else cout<<"该边不存在"<<endl;
  caldegree(G,op);
return 0;
}

如果不是连续的就按照输入顺序输出单链表

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e3;
typedef int LL;
typedef struct LNode* ToNode;
typedef struct Graph* ToGraph;
typedef struct LNode{///单链表
    LL num;///顶点编号
    LL val;///表头节点到直连点的边权
    LL indegree;///表头节点存下该点的入度
    LL outdegree;///表头节点存下该点的出度
    ToNode Next;
}LNode;
typedef struct Graph{
    ToNode A[maxn];
    LL graphnodes;///图的顶点数
    LL graphedges;///图的边数
}Graph;
void addnode(ToGraph &G,LL _v1,LL _v2){
    ToNode p=(ToNode)malloc(sizeof(LNode));
    p=(G->A[_v1]);
    while( p->Next!=nullptr ){
        p=p->Next;
        if(p->num==G->A[_v2]->num) return;///重边只有一次顶点
        if(p==nullptr) break;
    }
    ToNode k=(ToNode)malloc(sizeof(LNode));
    p->Next=k;
    k->num=G->A[_v2]->num;
    k->Next=nullptr;
    return;
}
LL findnum(ToGraph& G,LL v){
    for(LL i=1;i<=G->graphnodes;i++){
        if(G->A[i]->num==v) return i;
    }
    return 0;
}
void find(ToGraph &G,LL v1,LL v2){
        LL _v1=findnum(G,v1);
        LL _v2=findnum(G,v2);
      ///  debug(_v1);debug(_v2);
        if(G->A[_v1]->num==v1){
            addnode(G,_v1,_v2);
            cout<<"找到"<<v1<<"顶点"<<endl;
            G->A[_v1]->outdegree++;///该点出度++
        }
        if(G->A[_v2]->num==v2){
            G->A[_v2]->indegree++;///该点入读++
        }
}
void CreateGraph(ToGraph& G,LL op){
    G=(ToGraph)malloc(sizeof(Graph));
    if(op==0) cout<<"要构建的无向图的顶点数目:"<<endl;
    else if(op==1) cout<<"要构建的有向图的点数目:"<<endl;
    cin>>(G->graphnodes);
    if(op==0) cout<<"要构建的无向图的边的数目:"<<endl;
    else if(op==1) cout<<"要构建的有向图的边数目:"<<endl;
    cin>>(G->graphedges);
    for(LL i=1;i<=(G->graphnodes);i++){
        LL v;
        cout<<"顶点为:";cin>>v;
        G->A[i]=(ToNode)malloc(sizeof(LNode));
        G->A[i]->num=v;
        G->A[i]->indegree=0;
        G->A[i]->outdegree=0;
        G->A[i]->Next=nullptr;
    }
    for(LL i=1;i<=(G->graphedges);i++){
        cout<<"请输入边(vi,vj)上的顶点信息"<<endl;
        LL v1,v2;///v1<---->v2
        cin>>v1>>v2;
        if(op==0){
            find(G,v1,v2);
            find(G,v2,v1);
        }
        else if(op==1){
            find(G,v1,v2);
        }
    }
    cout<<"构造完成"<<endl;
}
void showGraph(ToGraph& G){
    cout<<"按输入顺序所建立的邻接表如下:"<<endl;
    for(LL i=1;i<=G->graphnodes;i++){///按顺序输出单链表
        ///LL v=findnum(G,i);///找标号为i的点
        cout<<"标号为"<<G->A[i]->num<<"的点:";
        ToNode p=G->A[i];
        if(p->Next==nullptr){
            cout<<"该点没有相连点";
        }
        else{
            while(p->Next!=nullptr){
                p=p->Next;
                cout<<" "<<p->num<<" ";
            }
        }
        cout<<endl;
    }
}
bool checkedge(ToGraph& G){
    LL v1,v2;
    cout<<"输入边的端点v1:";cin>>v1;
    cout<<"输入边的端点v2:";cin>>v2;
    LL _v1=findnum(G,v1);
    ToNode p=G->A[_v1];
    if(p->Next==nullptr) return 0;
    while(p->Next!=nullptr){
        p=p->Next;
        if(p->num==v2) return 1;
    }
    return 0;
}
void caldegree(ToGraph& G,LL op){///计算入度和出度
     if(op==1){
        for(LL i=1;i<=G->graphnodes;i++){
            cout<<"当前点为"<<G->A[i]->num<<":";
            cout<<"该点"<<G->A[i]->num<<"的入度为:"<<G->A[i]->indegree<<endl;
            cout<<"该点"<<G->A[i]->num<<"的出度为:"<<G->A[i]->outdegree<<endl;
            cout<<endl;
        }
     }
     else{
         for(LL i=1;i<=G->graphnodes;i++){
            cout<<"当前点为"<<G->A[i]->num<<":";
            cout<<"该点"<<G->A[i]->num<<"的度数为:"<<G->A[i]->indegree<<endl;
            cout<<endl;
        }
     }
}
int main(void)
{
  ///cin.tie(0);std::ios::sync_with_stdio(false);
  ToGraph G;
  cout<<"选择构建无向图(输入0)or有向图(输入1)"<<endl;
  LL op;cin>>op;
  if(op==0){
    CreateGraph(G,0);///无向图
  }
  else if(op==1){
    CreateGraph(G,1);///有向图
  }
  cout<<"fuck"<<endl;
  showGraph(G);
  cout<<"判断边是否存在"<<endl;
  if(checkedge(G)){
    cout<<"该边存在"<<endl;
  }
  else cout<<"该边不存在"<<endl;
  caldegree(G,op);
return 0;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
邻接表是一种常见的图的存储方式,可以用于存储有向图和无向图。下面是邻接表创建无向图的步骤: 1. 定义一个邻接表数据结构,一般包含两个部分:节点数组和邻接表数组。 2. 定义节点结构体,包含节点的值和指向第一个邻接节点的指针。 3. 初始化邻接表数组,将每个元素的指针初始化为 NULL。 4. 读取无向图的边信息,对于每条边 (u, v),在节点 u 和节点 v 的邻接表中分别添加一个指向对方节点的指针。 5. 如果无向图中存在自环边,即 (u, u),则在节点 u 的邻接表中只添加一个指向自己的指针。 6. 最后输出邻接表即可。 下面是用 C++ 代码实现的邻接表创建无向图的过程: ```c++ #include <iostream> #include <vector> using namespace std; // 节点结构体 struct Node { int val; // 节点的值 Node* next; // 指向下一个邻接节点的指针 }; // 邻接表数据结构 class AdjacencyList { public: // 构造函数 AdjacencyList(int n) { nodes.resize(n); for (int i = 0; i < n; i++) { nodes[i].val = i; // 节点值初始化为下标 nodes[i].next = NULL; } } // 添加无向图边 void addEdge(int u, int v) { Node* node_u = &nodes[u]; while (node_u->next != NULL) { node_u = node_u->next; } Node* new_node_u = new Node(); new_node_u->val = v; new_node_u->next = NULL; node_u->next = new_node_u; Node* node_v = &nodes[v]; while (node_v->next != NULL) { node_v = node_v->next; } Node* new_node_v = new Node(); new_node_v->val = u; new_node_v->next = NULL; node_v->next = new_node_v; } // 输出邻接表 void printList() { for (int i = 0; i < nodes.size(); i++) { Node* node = &nodes[i]; cout << node->val << " -> "; while (node->next != NULL) { node = node->next; cout << node->val << " -> "; } cout << "NULL" << endl; } } private: vector<Node> nodes; // 节点数组 }; int main() { int n, m; // n 个节点,m 条边 cin >> n >> m; AdjacencyList list(n); // 创建邻接表 for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; list.addEdge(u, v); // 添加无向图边 } list.printList(); // 输出邻接表 return 0; } ``` 上述代码中,我们首先定义了一个节点结构体 `Node`,包括节点的值和指向下一个邻接节点的指针。然后定义了一个邻接表数据结构 `AdjacencyList`,包括节点数组和邻接表数组,其中节点数组中每个元素表示一个节点,邻接表数组中每个元素表示一个节点的邻接表。在 `AdjacencyList` 类中,我们实现了添加无向图边和输出邻接表的方法。在 `main` 函数中,我们读取节点数和边数,然后创建邻接表并添加边,最后输出邻接表

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值