c++邻接表表示法创建无向图

---

---



# 6. 图

## 6.1 图的定义和术语

![image-20220928144100835](I:\数据结构-王卓\笔记难点\Figure\image-20220928144100835.png)

![image-20220928144133239](I:\数据结构-王卓\笔记难点\Figure\image-20220928144133239.png)

> ![image-20220928144739505](I:\数据结构-王卓\笔记难点\Figure\image-20220928144739505.png)
>
> > - **<vi,vj>**是弧,表示由**vi指向vj**,是一个**有向的弧**,称作**vi邻接到vj,vj邻接于vi**

 ![image-20220928145319377](I:\数据结构-王卓\笔记难点\Figure\image-20220928145319377.png)

![image-20220928145440734](I:\数据结构-王卓\笔记难点\Figure\image-20220928145440734.png)

![image-20220928145725286](I:\数据结构-王卓\笔记难点\Figure\image-20220928145725286.png)

![image-20220928150626564](I:\数据结构-王卓\笔记难点\Figure\image-20220928150626564.png)

![image-20220928150753034](I:\数据结构-王卓\笔记难点\Figure\image-20220928150753034.png)

![image-20220928151020012](I:\数据结构-王卓\笔记难点\Figure\image-20220928151020012.png)

![image-20220928151118796](I:\数据结构-王卓\笔记难点\Figure\image-20220928151118796.png)

![image-20220928151220145](I:\数据结构-王卓\笔记难点\Figure\image-20220928151220145.png)

## 6.2 案例引入

案例一:六度空间理论

![image-20220928151457413](I:\数据结构-王卓\笔记难点\Figure\image-20220928151457413.png)

## 6.3 图的类型定义

![image-20220928151549678](I:\数据结构-王卓\笔记难点\Figure\image-20220928151549678.png)

![image-20220928151612618](I:\数据结构-王卓\笔记难点\Figure\image-20220928151612618.png)

![image-20220928151921842](I:\数据结构-王卓\笔记难点\Figure\image-20220928151921842.png)

## 6.4 图的存储结构

![image-20220928160425033](I:\数据结构-王卓\笔记难点\Figure\image-20220928160425033.png)

### 6.4.1 邻接矩阵

#### 6.4.1.1 无向图的邻接矩阵

![image-20220928160542500](I:\数据结构-王卓\笔记难点\Figure\image-20220928160542500.png)

![image-20220928160820907](I:\数据结构-王卓\笔记难点\Figure\image-20220928160820907.png)

#### 6.4.1.2 有向图的邻接矩阵

![image-20220928161157106](I:\数据结构-王卓\笔记难点\Figure\image-20220928161157106.png)

#### 6.4.1.3 网的邻接矩阵

![image-20220928161326723](I:\数据结构-王卓\笔记难点\Figure\image-20220928161326723.png)

#### 6.4.1.4 邻接矩阵的存储表示和代码

**邻接矩阵的存储表示 :**   用两个数组分别存储**顶点表**和**邻接矩阵**

***图的定义***

```c++
struct AMGraph
{
    //图的顶点向量
    char Vexs[MAXSIZE];
    //图的邻接矩阵
    int Arcs[MAXSIZE];
    //图的总顶点数和总边数
    int vexnum, arcnum;
};
```

***创建无向网***

```c++
void CreatUDN(AMGraph &G)
{
    //第一步:输入无向图的顶点数目
    cout << "input num" << endl;
    cin >> G.arcnum >> G.arcnum; //输入总顶点数和总边数
    //第二步:输入结点的名称,保存在一维数组中
    cout << "input vexs" << endl;
    for (int i = 0; i < G.vexnum; ++i)
    {
        cin >> G.vexs[i];
    }
    //第三步:将邻接矩阵的元素值置为无穷大
    for (int i = 0; i < G.arcnum; ++i)
    {
        for (int j = 0; j < G.arcnum; ++j)
        {
            G.arcs[i][j] = INT32_MAX;
        }
    }
    //第四步:输入顶点相互关系以及权重
    for (int k = 0; k < G.arcnum;++k)
    {
        int i, j, weight;
        char a, b;
        cin >> a >> b >> weight;
        //由输入的顶点a和b查找到对应的下标i,j
        i = LocateVex(G,a)
        j = LocateVex(G,b)
        G.arcs[i][j] = G.arcs[j][i] = weight;
    }
}
```

***邻接矩阵的LocateVex函数***

~~~cpp
int LocateVex(AMGraph &G, const char &e)
{
    for (int i = 0; i < G.vexnum;++i)
    {
        if(G.vexs[i]==e)
            return i;
    }
    return -1;
}
~~~

![image-20220928161627222](I:\数据结构-王卓\笔记难点\Figure\image-20220928161627222.png)

![image-20220928161746176](I:\数据结构-王卓\笔记难点\Figure\image-20220928161746176.png)

![image-20220928162033687](I:\数据结构-王卓\笔记难点\Figure\image-20220928162033687.png)

![image-20220928162200324](I:\数据结构-王卓\笔记难点\Figure\image-20220928162200324.png)

![image-20220928162105887](I:\数据结构-王卓\笔记难点\Figure\image-20220928162105887.png)

![image-20220928163333558](I:\数据结构-王卓\笔记难点\Figure\image-20220928163333558.png)

#### 6.4.1.5 邻接矩阵的优缺点

![image-20220928163433341](I:\数据结构-王卓\笔记难点\Figure\image-20220928163433341.png)

![image-20220928163611525](I:\数据结构-王卓\笔记难点\Figure\image-20220928163611525.png)

### 6.4.2 邻接表

#### 6.4.2.1 邻接表表示法(链式)

![image-20220928164117420](I:\数据结构-王卓\笔记难点\Figure\image-20220928164117420.png)

#### 6.4.2.2无向图的邻接表

![image-20220928164353171](I:\数据结构-王卓\笔记难点\Figure\image-20220928164353171.png)

#### 6.4.2.3 有向图的邻接表

![image-20220928164547277](I:\数据结构-王卓\笔记难点\Figure\image-20220928164547277.png)

![image-20220928164632759](I:\数据结构-王卓\笔记难点\Figure\image-20220928164632759.png)

#### 6.4.2.4 邻接表的存储表示和代码

![image-20220928164949900](I:\数据结构-王卓\笔记难点\Figure\image-20220928164949900.png)

![image-20220928165032991](I:\数据结构-王卓\笔记难点\Figure\image-20220928165032991.png)

![image-20220928170457317](I:\数据结构-王卓\笔记难点\Figure\image-20220928170457317.png)

![image-20220929140433965](I:\数据结构-王卓\笔记难点\Figure\image-20220929140433965.png)

***邻接表定义代码***

~~~cpp
//顶点的结点定义  (表头)
typedef struct VNode
{
    //数据域,存放顶点信息
    VecTexType data;
    //指针域,指向第一条依附该顶点的边的指针 / ArcNode *p  /  p->adjvex 即边指向顶点的位置编号
    ArcNode *firstarc;
} AdjList[MVNum]; //AdjList表示邻接表类型

//弧(边)的结点定义 
struct ArcNode
{
    int adjvex;       //该边指向顶点的的位置编号
    int weight;       //保存边的权重
    ArcNode *nextarc; //指向下一个边的指针 ArcNode      //形成嵌套,不断形成指向下一个弧(边)的指针
};

//图定义
struct ALGraph
{
    //定义一个数组,保存图的顶点  Maxsize = vexnum 顶点个数
    VNode vexs[MAXSIZE];   //  AdjList vertices  //  VNode结构体(第一段代码)
    //定义两个变量,保存当前图的顶点个数以及边的条数
    int vexnum, arcnum;
};
~~~

![image-20220929140904114](I:\数据结构-王卓\笔记难点\Figure\image-20220929140904114.png)

![image-20220929140958115](I:\数据结构-王卓\笔记难点\Figure\image-20220929140958115.png)

![image-20220929141251848](I:\数据结构-王卓\笔记难点\Figure\image-20220929141251848.png)

***创建无向图算法***

![image-20220929151336903](I:\数据结构-王卓\笔记难点\Figure\image-20220929151336903.png)

~~~cpp
void CreatUDG(ALGraph &G)
{
    //输入图的顶点个数以及边的条数
    cout << "info" << endl;
    cin >> G.vexnum >> G.arcnum;
    //给顶点向量赋值
    for (int i = 0; i < G.vexnum; ++i)
    {
        cin >> G.vexs[i].data;
        G.vexs[i].firstarc = NULL;
    }
    
    //输入各边构建连接表 / 输入一条边依附的两个顶点
    for (int j = 0; j < G.arcnum; ++j)
    {
        cout << "input info about arc" << endl;
        char a, b;
        //int w;
        cin >> a >> b;
        int i = LocateVex(G, a); //定位a结点的编号
        int j = LocateVex(G, b); 
        
     // 出度边的构建 ArcNode
*p1 = new ArcNode;//生成一个新的边节点*p1 p1->adjvex = j; //邻接点序号为j //p1->weight = w1; //权重1 p1->nextarc = G.vexs[i].firstarc; // 当前G.vexs[i].firstarc为NULL G.vexs[i].firstarc = p1; //将新节点*p1插入顶点vi的边表头部 (头插法)      // 入度边的构建 ArcNode *p2 = new ArcNode; p2->adjvex = i; //p2->weight = w2; //权重2 p2->nextarc = G.vexs[j].firstarc; G.vexs[j].firstarc = p2; } }

由于是无向表,因此可以需要构建入度和出度表。有向表就只需要构建一个。。

为什么说是头插法?特地画了个图

 

posted @ 2022-09-29 15:22  爱吃牛牛的康康  阅读(177)  评论(0)    收藏  举报