[Data Structure] [Figure] [Adjacency Matrix] A question to realize the insertion and deletion of edges and reflection of the adjacency matrix

It is assumed that the data elements of the undirected and unweighted graph are characters, and the adjacency list storage structure is adopted. The implementation code operations of most operations such as graph creation and storage structure output have been given. Please add and write the implementation function codes for inserting edges and deleting edges respectively.

1. Relevant instructions:

1. Insert edge, int Insert_Edge(g,vi,vj)

Input: graph g, two vertex elements vi, vj to be inserted into the edge;

Output: Return the status of the insertion (success, error: edge vertex does not exist, error: edge duplicate), and output according to different states:

​ Error:Vertex does not exist!

​ Error:Edge repetition!

​ Edge insertion succeeded!

Note: For uniformity, when the adjacent point is linked into the linked list, the link is at the front (header position)

2. Delete edge, int Delete_Edge(g,vi,vj)

Input: graph g, the two vertex elements vi and vj of the edge to be deleted;

Output: Return the status of deletion (success, error: edge vertex does not exist, error: edge does not exist), and output according to different states:

​ Error:Vertex does not exist!

​ Error:Edge does not exist!

​ Edge deletion succeeded!

3. Operation control in the main function: 1—Create graph 2—Storage structure of output graph 3—Insert edge 4—Delete edge 0—Exit

When creating a graph, you need to input the number of vertices, each vertex element, and each edge, see the example for details;

When outputting the storage structure, see the example for the output format;

When inserting or deleting an edge, two vertex elements of the edge need to be input;

2. Please complete the code as follows:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define   Max_VertexNum 50     //允许图的顶点个数的最大值
typedef   char  VertexType;  //定义数据元素(顶点)类型为char
//********************************************************************************
//邻接表存储结构
struct  EdgeNode   //定义边存储结点
{
    
     int adjvex;        //邻接点的存储位置
EdgeNode  *next;   //指向下邻接点
};      

struct VertexNode   //定义顶点存储结点
{
    
     VertexType vertex;       //数据元素
struct EdgeNode *link;   //第一个邻接点
};          

typedef struct Graph   //定义邻接表图结构
{
    
     int VexNum;        //图的顶点个数
VertexNode Nodetable[Max_VertexNum];   //一维数组-邻接表    
}  Graphlnk;      //定义邻接表存储的图类型
//**********************************************************************************
// 基于邻接表存储的 无向、非加权图的各种操作的实现
//** 创建图
void create_graph(Graphlnk &g)
{
    
    	VertexType v1, v2;
    int i, j;
    struct  EdgeNode *p, *q;
    cin >> g.VexNum;  //读入图的顶点个数
    while (g.VexNum < 0)
        cin >> g.VexNum;
    for (i = 0; i < g.VexNum; i++)
    {
    
    	cin >> g.Nodetable[i].vertex;    //输入顶点元素
        g.Nodetable[i].link = NULL;      //邻接表初始化
    }
    cin >> v1 >> v2;     //输入边的两个顶点
    while (v1 != '*'&&v2 != '*')
    {
    
       for (i = 0; i < g.VexNum; i++)
            if (g.Nodetable[i].vertex == v1) break;
        for (j = 0; j < g.VexNum; j++)
            if (g.Nodetable[j].vertex == v2) break;
        if (i >= g.VexNum || j >= g.VexNum)  cin >> v1 >> v2;    //边顶点不正确,重新读
        else      //链入邻接点
        {
    
    	p = (struct  EdgeNode *)malloc(sizeof(struct  EdgeNode));
            p->adjvex = j;
            p->next = g.Nodetable[i].link;
            g.Nodetable[i].link = p;
            q = (struct  EdgeNode *)malloc(sizeof(struct  EdgeNode));
            q->adjvex = i;
            q->next = g.Nodetable[j].link;
            g.Nodetable[j].link = q;
            cin >> v1 >> v2;
        }
    }
}

void print_graph(Graphlnk  g)
{
    
    	int i;
    struct  EdgeNode *p;
    cout << "Adjacency List is:" << endl;
    for (i = 0; i < g.VexNum; i++)
    {
    
    	cout << g.Nodetable[i].vertex << ":";
        p = g.Nodetable[i].link;
        while (p != NULL)
        {
    
    	cout << "-->" << g.Nodetable[p->adjvex].vertex;
            p = p->next;
        }
        cout << endl;
    }
}
//**********************************************************************
     补充 插入边、删除边的函数
//**********************************************************************
int main()
{
    
    	Graphlnk g;
    int ic;
    VertexType vi, vj;
    int k;
    while (1)
    {
    
        //请输入要执行的操作:";
        cin >> ic;
        while (ic < 0 || ic>4)
            cin >> ic;
        if (ic == 1)  create_graph(g);    //创建图
        if (ic == 2)  print_graph(g);       //输出图结构
        if (ic == 3)     //插入边
        {
    
     cin >> vi >> vj;
            k = Insert_Edge(g, vi, vj);
            if (k == -1) cout << "Error:Vertex does not exist!" << endl;
            if(k==0) cout << "Error:Edge repetition!" << endl;
            if(k==1) cout << "Edge insertion succeeded!" << endl;
        }
        if (ic == 4)     //删除边
        {
    
     cin >> vi >> vj;
            k = Delete_Edge(g, vi, vj);
            if (k == -1) cout << "Error:Vertex does not exist!." << endl;
            if (k == 0) cout << "Error:Edge does not exist!" << endl;
            if (k == 1) cout << "Edge deletion succeeded!" << endl;
        }
        if (ic == 0)  break;
    }
    return 0;
}

3. Answer as follows↓

int prjIns1(Graphlnk  &g,VertexType vi,VertexType vj,int i,int j,struct EdgeNode *ptr1,struct EdgeNode *ptr2,struct EdgeNode *p,struct EdgeNode *q){
    
    
    if(ptr1==NULL){
    
    
        p = (struct  EdgeNode *)malloc(sizeof(struct  EdgeNode));
        p->adjvex = j;
        p->next = g.Nodetable[i].link;
        g.Nodetable[i].link = p;
        return 1;
    }
    if(ptr1!=NULL){
    
    
        if(ptr1->adjvex==j)
            return 0;
        else{
    
    
            while(ptr1->next!=NULL){
    
    
                ptr1=ptr1->next;
                if(ptr1->adjvex==j)
                    return 0;
            }
            p = (struct  EdgeNode *)malloc(sizeof(struct  EdgeNode));
            p->adjvex = j;
            p->next = ptr1->next;
            ptr1->next = p;
            return 1;
        }
    }
}

int prjIns2(Graphlnk  &g,VertexType vi,VertexType vj,int i,int j,struct EdgeNode *ptr1,struct EdgeNode *ptr2,struct EdgeNode *p,struct EdgeNode *q){
    
    
    if(ptr2==NULL){
    
    
        q = (struct  EdgeNode *)malloc(sizeof(struct  EdgeNode));
        q->adjvex = i;
        q->next = g.Nodetable[j].link;
        g.Nodetable[j].link = q;
        return 1;
    }
    if(ptr2!=NULL){
    
    
        if(ptr2->adjvex==i)
            return 0;
        else{
    
    
            while(ptr2->next!=NULL){
    
    
                ptr2=ptr2->next;
                if(ptr2->adjvex==i)
                    return 0;
            }
            q = (struct  EdgeNode *)malloc(sizeof(struct  EdgeNode));
            q->adjvex = i;
            p->next = ptr2->next;
            ptr2->next = p;
            return 1;
        }
    }
}

int Insert_Edge(Graphlnk  &g,VertexType vi,VertexType vj){
    
    
    int i,j;
    struct  EdgeNode *p, *q;

    for (i = 0; i < g.VexNum; i++){
    
    
        if (g.Nodetable[i].vertex == vi)break;
        if(i==g.VexNum-1)
            return -1;
    }
    for (j = 0; j < g.VexNum; j++){
    
    
        if (g.Nodetable[j].vertex == vj)break;
        if(j==g.VexNum-1)
            return -1;
    }


    struct EdgeNode *ptr1=g.Nodetable[i].link;
    struct EdgeNode *ptr2=g.Nodetable[j].link;


    int ins1,ins2;
    ins1=prjIns1(g,vi,vj,i,j,ptr1,ptr2,p,q);
    ins2=prjIns2(g,vi,vj,i,j,ptr1,ptr2,p,q);
    if(ins1==1&&ins2==1)
        return 1;
    else
        return 0;
}


int prjDel1(Graphlnk  &g,VertexType vi,VertexType vj,int i,int j,struct EdgeNode *ptr1,struct EdgeNode *ptr2){
    
    
    if(ptr1==NULL){
    
    
        return 0;
    }
    if(ptr1!=NULL){
    
    
        if(ptr1->adjvex==j&&ptr1->next!=NULL){
    
    
            g.Nodetable[i].link=ptr1->next;
            return 1;
        }
        if(ptr1->adjvex==j&&ptr1->next==NULL){
    
    
            g.Nodetable[i].link=NULL;
            return 1;
        }
        if(ptr1->adjvex!=j&&ptr1->next!=NULL){
    
    
            while (ptr1->next->adjvex!=j&&ptr1->next!=NULL){
    
    

                ptr1=ptr1->next;

            }
            if(ptr1->next==NULL)
                return 0;
            if(ptr1->next->adjvex==j){
    
    
                ptr1->next=ptr1->next->next;
                return 1;
            }
        }
        if(ptr1->adjvex!=j&&ptr1->next==NULL){
    
    
            return 0;
        }
    }
}

int prjDel2(Graphlnk  &g,VertexType vi,VertexType vj,int i,int j,struct EdgeNode *ptr1,struct EdgeNode *ptr2){
    
    
    if(ptr2==NULL){
    
    
        return 0;
    }
    if(ptr2!=NULL){
    
    
        if(ptr2->adjvex==i&&ptr2->next!=NULL){
    
    
            g.Nodetable[j].link=ptr2->next;
            return 1;
        }
        if(ptr2->adjvex==i&&ptr2->next==NULL){
    
    
            g.Nodetable[j].link=NULL;
            return 1;
        }
        if(ptr2->adjvex!=i&&ptr2->next!=NULL){
    
    
            while (ptr2->next->adjvex!=i&&ptr2->next!=NULL){
    
    

                ptr2=ptr2->next;

            }
            if(ptr2->next==NULL)
                return 0;
            if(ptr2->next->adjvex==i){
    
    
                ptr2->next=ptr2->next->next;
                return 1;
            }
        }
        if(ptr2->adjvex!=i&&ptr2->next==NULL){
    
    
            return 0;
        }
    }
}

int Delete_Edge (Graphlnk  &g,VertexType vi,VertexType vj){
    
    
    int i,j;
    struct  EdgeNode *p, *q;
    for (i = 0; i < g.VexNum; i++){
    
    
        if (g.Nodetable[i].vertex == vi)break;
        if(i==g.VexNum-1)
            return -1;
    }
    for (j = 0; j < g.VexNum; j++){
    
    
        if (g.Nodetable[j].vertex == vj)break;
    }

    struct EdgeNode *ptr1=g.Nodetable[i].link;
    struct EdgeNode *ptr2=g.Nodetable[j].link;

    int del1,del2;
    del1= prjDel1(g,vi,vj,i,j,ptr1,ptr2);
    del2= prjDel2(g,vi,vj,i,j,ptr1,ptr2);
    if(del1==1&&del2==1)
        return 1;
    if(del1==0)
        return 0;
}

4. Reflection

1. Find the problem

It can be slightly functional at the beginning, but a slightly more complicated input will cause more bugs .

2. Solve and implement

(1) Think about the possible branches of each step before starting each link of the program design , and then implement them in turn, and finally simplify, first complicated and then separated, so as to prevent unexpected situations from happening;

(2) When implementing different branches, I found that if it is a statement like if()if()if(), the influence of the former if() on the later if() should be considered. For example, after experiencing the former if() may After if() is implemented unexpectedly, the problem of modifying two pointer data at the same time is particularly prominent, mainly because not every if() has a return ;

(3) As long as there is a return in each if, the problem of (2) can be solved. In this question, I built a small function to realize this function.

Guess you like

Origin blog.csdn.net/m0_50939789/article/details/122253027