图的基本运算及智能交通中的最佳路径选择问题(实验三)

1.编写程序,实现邻接矩阵的初始化、撤销、边的搜索、插入、删除等操作

/*数据结构实验三
完成邻接矩阵的初始化,撤销,边的搜索,插入,删除等操作 */
#include
using namespace std;
typedef int ElemType;
typedef struct{
    ElemType **a;   //邻接矩阵 
    int n;      //图的顶点数 
    int e;      //图当前的边数 
    ElemType noEdge;    //两顶点无边时的值 
}mGraph;



//初始化,nSize顶点数,noEdgeValue无边的值 
int Init(mGraph *mg,int nSize,ElemType noEdgeValue){
    int i,j;
    mg->n=nSize;
    mg->e=0;        //初始化没有边 
    mg->noEdge=noEdgeValue;
    mg->a=(ElemType**)malloc(nSize*sizeof(ElemType*));  //生成长度为n的一维数组指针
    if(!mg->a) return 0;
    for(int i=0;in;i++){
        mg->a[i]=(ElemType*)malloc(nSize*sizeof(ElemType));
        for(j=0;jn;j++) mg->a[i][j]=mg->noEdge;
        mg->a[i][i]=0;                                  //自回路设置为0 
    } 
    return 1;
} 
//撤销操作,撤销的时候顺序不能变,先释放指针数组就会找不到数组指针啦 
int Destory(mGraph *mg){
    int i;
    for(int i=0;in;i++) free(mg->a[i]);    //释放n个一维数组存储空间 
    free(mg->a);                                //释放n个一维指针数组的存储空间 
    return 1;
} 
//边的搜索操作,判断边在不在图中 
int Exist(mGraph *mg,int u,int v){
    if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v||mg->a[u][v]==mg->noEdge){
        cout<<"这条边不存在."<return 0;
    }
    cout<<"这条边存在."<cout<<"这条边的长度为:"<a[u][v]<return 1;
} 
//边的插入
int Insert(mGraph *mg,int u,int v,ElemType w){
    if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v) return 0;
    if(mg->a[u][v]!=mg->noEdge) {
        cout<<"该边已存在."<return 0; 
    }
    mg->a[u][v]=w;
    mg->e++;
    return 1;
} 

//边的删除
int Remove(mGraph *mg,int u,int v){
    if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v)
    return 0;
    if(mg->a[u][v]==mg->noEdge) return 0;   //删除的边不存在
    mg->a[u][v]=mg->noEdge;
    mg->e--;
    return 1; 
} 

int main(){
    mGraph mg;
    int n,n1,u,v,w,a,b;
//  fangxin();
//  fx();
    cout<<"请输入顶点的个数:"<cin>>n;         
    Init(&mg,n,0);
    cout<<"请输入插入边的个数:"<cin>>n1;
    cout<<"请输入插入边的起点(顶点计算从0开始)、终点和边权:"<for(int i=0;icin>>u>>v>>w;
        Insert(&mg,u,v,w);
    }
    cout<<"请输入查找的边的两个端点:"<cin>>a>>b;
    Exist(&mg,a,b);
    Destory(&mg);
    Remove(&mg,0,1);
    system("pause");
    return 0;
} 

2.以邻接矩阵所示的邻接矩阵为存储结构,编写程序,实现图的深度和宽度遍历。

//邻接矩阵实现深度和宽度遍历
 /*数据结构实验三
完成邻接矩阵的初始化,撤销,边的搜索,插入,删除等操作 */
#include
#include
using namespace std;
typedef int ElemType;
typedef struct{
    ElemType **a;   //邻接矩阵 
    int n;      //图的顶点数 
    int e;      //图当前的边数 
    ElemType noEdge;    //两顶点无边时的值 
}mGraph;

//初始化,nSize顶点数,noEdgeValue无边的值 
int Init(mGraph *mg,int nSize,ElemType noEdgeValue){
    int i,j;
    mg->n=nSize;
    mg->e=0;        //初始化没有边 
    mg->noEdge=noEdgeValue;
    mg->a=(ElemType**)malloc(nSize*sizeof(ElemType*));  //生成长度为n的一维数组指针
    if(!mg->a) return 0;
    for(int i=0;in;i++){
        mg->a[i]=(ElemType*)malloc(nSize*sizeof(ElemType));
        for(j=0;jn;j++) mg->a[i][j]=mg->noEdge;
        mg->a[i][i]=0;                                  //自回路设置为0 
    } 
    return 1;
} 
//撤销操作,撤销的时候顺序不能变,先释放指针数组就会找不到数组指针啦 
int Destory(mGraph *mg){
    int i;
    for(int i=0;in;i++) free(mg->a[i]);    //释放n个一维数组存储空间 
    free(mg->a);                                //释放n个一维指针数组的存储空间 
    return 1;
} 
//边的搜索操作,判断边在不在图中 
int Exist(mGraph *mg,int u,int v){
    if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v||mg->a[u][v]==mg->noEdge){
        cout<<"这条边不存在."<return 0;
    }
    cout<<"这条边存在."<cout<<"这条边的长度为:"<a[u][v]<return 1;
} 
//边的插入
int Insert(mGraph *mg,int u,int v,ElemType w){
    if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v) return 0;
    if(mg->a[u][v]!=mg->noEdge) {
        cout<<"该边已存在."<return 0; 
    }
    mg->a[u][v]=w;
    mg->e++;
    return 1;
} 

//边的删除
int Remove(mGraph *mg,int u,int v){
    if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v)
    return 0;
    if(mg->a[u][v]==mg->noEdge) return 0;   //删除的边不存在
    mg->a[u][v]=mg->noEdge;
    mg->e--;
    return 1; 
} 
void dfs(mGraph mg,int i,int visited[]){
    visited[i]=1;
    cout<" ";
    for(int j=0;jif(mg.a[i][j]!=0&&visited[j])
            dfs(mg,j,visited);
    }
}
void dfsGraph(mGraph mg,int visited[]){
    int i;
    for(int i=0;i0;
    for(int i=0;iif(!visited[i])
            dfs(mg,i,visited);
    }       
}

int bfsGraph(mGraph *mg,int visited[]){
    int i,j;
    queue<int> q;
    for(int i=0;in;i++) visited[i]=0;
    for(int i=0;in;i++){
        if(!visited[i]){
            visited[i]=1;
            cout<" ";
            q.push(i);
            while(!q.empty()){
                q.pop();
                for(int j=0;jn;j++){
                    if(!visited[j]&&mg->a[i][j]!=0){
                        visited[j]=1;
                        cout<" ";
                        q.pop();
                    }
                }
            }
        }
    }
}

int main(){
    mGraph mg;
    int n,n1,u,v,w,a,b,visited[10010];
    memset(visited,0,sizeof(visited));

    cout<<"请输入顶点的个数:"<cin>>n;         
    Init(&mg,n,0);
    cout<<"请输入插入边的个数:"<cin>>n1;
    cout<<"请输入插入边的起点(顶点计算从0开始)、终点和边权:"<for(int i=0;icin>>u>>v>>w;
        Insert(&mg,u,v,w);
    }

    cout<<"邻接矩阵存储下,图的深度遍历访问过的结点:";
    dfsGraph(mg,visited);
    cout<cout<<"邻接矩阵存储下,图的宽度遍历访问过的结点:";
    bfsGraph(&mg,visited);
    cout<"pause");
    return 0;
} 

3.实现邻接表的初始化、撤销、边的搜索、插入、删除等操作

//以邻接矩阵为存储结构,实现图的深度、宽度、深度优先遍历 
#include
using namespace std;
typedef int ElemType;
typedef struct Enode{
    int adjVex;     //任意顶点u相邻的点
    ElemType w;     //边的权值
    struct Enode* nextArc;  //指向下一个边结点 
}Enode;
typedef struct{
    int n;  //结点个数
    int e;  //边的个数
    Enode **a;  //指向一维指针数组 
}Lgraph;

//初始化
int init(Lgraph *lg,int nSize) {
    lg->a=(Enode **)malloc(nSize*sizeof(Enode*));
    lg->n=nSize;
    lg->e=0;
    if(!lg->a) return 0;
    else {
        for(int i=0;ia[i]=NULL;
        }
        return 1;
    }   
}

//邻接表的撤销
int Destory(Lgraph *lg){
    int i;
    Enode *p,*q;
    for(int i=0;in;i++){
        p=lg->a[i];
        q=p;
        while(p){
            p=p->nextArc;
            free(q);
            q=p;
        }
    }
    free(lg->a);    //释放一维指针数组a的存储空间 
    return 1;
} 

//搜索边
int Exist(Lgraph *lg,int u,int v){
    Enode *p;
    if(u<0||v<0||u>=lg->n||v>lg->n||u==v) return 0;
    p=lg->a[u];
    while(p &&p->adjVex!=v){
        p=p->nextArc;
    }
    if(!p) return 0;
    else{
        cout<<"该边的权值为"<w<<",";
        return 1;
    }
} 

//插入边
int Insert(Lgraph *lg,int u,int v,int w){
    Enode *p;
    if(u<0||v<0||u>=lg->n||v>=lg->n||u==v) return 0;
    if(Exist(lg,u,v))  return 0;
    p=(Enode *) malloc(sizeof(Enode));  //为新生成的边分配存储空间
    p->adjVex=v;
    p->w=w; 
    p->nextArc=lg->a[u];    //插入结点在序列的开头 
    lg->a[u]=p;
    lg->e++;
    return 1; 
} 

//删除边
int Remove(Lgraph *lg,int u,int v){
    if(u<0||v<0||u>=lg->n||v>=lg->n||u==v) return 0;
    Enode *p,*q;
    p=lg->a[u];
    q=NULL;
    while(p &&p->adjVex!=v){
        q=p;
        p=p->nextArc;
    }
    if(!p) return 0;        //q是待删结点的前驱结点,p是待删结点 
    if(q) q->nextArc=p->nextArc;
    else  lg->a[u]=p->nextArc;
    free(q);
    lg->e--;
    return 1;
} 

int main(){
    Lgraph lg;
    int n,u,v,w;
    bool flag1,flag2,flag3;
    flag1=flag2=flag3=false;
    cout<<"请输入顶点的个数:"<cin>>n;
    init(&lg,n);
    cout<<"请输入插入的边的两个顶点和边权:(0 0 0表示输入结束)"<while(cin>>u>>v>>w){
        if(u==0 &&v==0 &&w==0) break;
        Insert(&lg,u,v,w);
    }

    cout<<"请输入待查找的边的两个顶点:"<cin>>u>>v;
    flag1=Exist(&lg,u,v);
    if(flag1) cout<<"该边存在."<else cout<<"该边不存在."<cout<cout<<"请输入待删除的边的两个顶点:"<cin>>u>>v;
    flag2=Remove(&lg,u,v);
    if(flag2) cout<<"删除成功."<else cout<<"删除失败."<cout<<"撤销邻接表."<if(flag3) cout<<"撤销成功."<else cout<<"撤销失败."<"pause");
    return 0;
}

4.以邻接表为存储结构,编写程序,实现图的深度和宽度遍历。

深度

//深度和宽度遍历图,邻接表存储 
#include
#define maxn 10010
using namespace std;
int visited[maxn];
typedef struct Enode{
    int adjVex;     //任意与u相邻的点
    int w;          //边权
    struct Enode *nextArc;  //指向下一个边结点 
}Enode;
typedef struct{
    int n,e;
    Enode **a;
}Lgraph;

//单一顶点深搜 
void dfs(int v,int visited[],Lgraph g){
    Enode *w;
    cout<" ";  //访问结点v
    visited[v]=1; 
    for(w=g.a[v];w ;w=w->nextArc)   //访问邻接点
    {
        if(!visited[w->adjVex]){
            dfs(w->adjVex,visited,g);
        }
    }
}
//初始化 
int init(Lgraph *lg,int nSize){
    lg->n=nSize;
    lg->e=0;
    lg->a=(Enode **)malloc(nSize*sizeof(Enode *));
    if(!lg->a) return 0;
    for(int i=0;in;i++){
        lg->a[i]=NULL;
    }
    return 1;   
}
//插入边
int Insert(Lgraph *lg,int u,int v,int w){
    if(u<0||v<0||u>lg->n-1||v>lg->n-1||u==v) return 0;
    Enode *p;
    p=(Enode *)malloc(sizeof(Enode));
    p->adjVex=v;
    p->w=w;
    p->nextArc=lg->a[u];
    lg->a[u]=p;         //这里注意,开始写错了,查了好久 
    lg->e++;
    return 1;   
} 

//全图深搜
void dfsGraph(Lgraph g){
    int i;
    int *visited=(int *)malloc(g.n*sizeof(int ));
    for(int i=0;i0;
    for(int i=0;iif(!visited[i]){
            dfs(i,visited,g);
        }
    }
    free(visited);
} 

int main(){
    Lgraph lg;
    int n,u,v,w,visited[maxn],p; 
    memset(visited,0,sizeof(visited));

    cout<<"请输入顶点的个数."<cin>>n;

    init(&lg,n);
    cout<<"请输入带插入边的两个端点和边权.(以0 0 0结尾)"<while(cin>>u>>v>>w){
        if(u==0 &&v==0 &&w==0) break;
        Insert(&lg,u,v,w);
    }

    cout<<"请输入搜索的起点."<cin>>u;
    //单一顶点深搜 
    cout<<"单一顶点深搜:";
    dfs(u,visited,lg);
    cout<//全图深搜 
    cout<<"全图深搜:";
    dfsGraph(lg);
    cout<cout<<"深搜结束"<"pause");
    return 0;
}

宽度:

//宽度遍历图,邻接表存储 
#include
#include
#define maxn 10010
using namespace std;
typedef struct Enode{
    int adjVex;     //相邻的结点 
    int w;  //边权 
    struct Enode * nextArc;
}Enode;
typedef struct{
    int n;      //顶点数
    int e;      //边数
    Enode **a;  //一维指针数组 
}Lgraph;

int init(Lgraph *lg,int nSize){
    lg->n=nSize;
    lg->e=0;
    lg->a=(Enode **)malloc(nSize*sizeof(Enode *));
    if(!lg->a) return 0;
    for(int i=0;in;i++)
    lg->a[i]=NULL;
    return 1;
}

int Insert(Lgraph *lg,int u,int v,int w){
    if(u<0||v<0||u>lg->n-1||v>lg->n-1||u==v) return 0;
    Enode *p;
    p=(Enode *)malloc(sizeof(Enode));
    p->adjVex=v;
    p->w=w;
    p->nextArc=lg->a[u];
    lg->a[u]=p;
    return 1;
}

int bfs(int v,int visited[],Lgraph g){
    Enode *w;
    queue<int > q;  //调用STL库
    visited[v]=1;
    cout<" ";
    q.push(v);
    while(!q.empty()){
        q.front();  //取队首元素 
        q.pop();    //队首元素出队
        for(w=g.a[v];w;w=w->nextArc){
            if(!visited[w->adjVex]){
                visited[w->adjVex]=1;
                cout<adjVex<<" ";
                q.push(w->adjVex);
            }
        } 
    }
}

int bfsGraph(Lgraph g){
    int i;
    int *visited=(int *)malloc(g.n*sizeof(int));
    for(int i=0;i0;
    for(int i=0;iif(!visited[i]) bfs(i,visited,g);
    }
    free(visited);
}

int main(){
    Lgraph lg;
    int n,visited[maxn],u,v,w,v1;
    memset(visited,0,sizeof(visited));

    cout<<"请输入顶点的个数."<cin>>n;

    init(&lg,n);
    cout<<"请输入带插入边的两个端点和边权.(以0 0 0结尾)"<while(cin>>u>>v>>w){
        if(u==0 &&v==0 &&w==0) break;
        Insert(&lg,u,v,w);
    }
    cout<<"请输入宽度搜算的起点:"<cin>>v1;
    cout<<"宽搜的结点:"; 
    bfs(v1,visited,lg);
    cout<cout<<"全图宽搜: "; 
    bfsGraph(lg);
    cout<"宽搜结束。"<return 0;
}

5.编写程序,实现智能交通中的最佳路径选择问题。

你可能感兴趣的:(图的基本运算及智能交通中的最佳路径选择问题(实验三))