数据结构与算法:图ADT的基本实现

假设图结构具有n个元素(顶点,n不大于500),数据元素为字符,如果是加权图,权值为整数。请编码实现图ADT。

存储结构的选择: 1: 邻接矩阵 2: 邻接表
执行的操作:1:创建图
2:输出图的存储结构(邻接矩阵或邻接表,格式见后面说明)
3:计算各个顶点的度(有向图时,分为入度和出度)
4:深度遍历(需要输入遍历开始顶点)
5:广度遍历(需要输入遍历开始顶点)
0:退出
注:(1)图的类型分为4种,
1:无向,不加权
2:有向,不加权
3:无向,加权
4:有向,加权
(2)边用一对顶点元素表示,权值为整数,例如非加权图边 ab,加权图ab6
操作相关说明:
运行时首先选择存储结构,输入1或2
然后选择要执行的操作,输入0-5中的一个,第1个操作必须是0或1
(1)创建图:
输入有多行,包括:
第一行,一个整数,指出图的类型,见前面说明。
第二行,一个整数,输入图的顶点个数
第三行,输入各个顶点元素字符
后面多行,输入两个字符表示顶点的各条边,如果是加权图,后面还有一个整数权值。当输入**字符时(需要权值时,任意)表示边的输入结束。
最后是要执行的操作
顶点按输入顺序存储;如果采用邻接表存储,输入边时邻接点采用插入到前面(所在链表头)
例如:
1 //邻接矩阵存储结构
1 //创建图
1 //无向,不加权图
6 //顶点个数
abcdef //顶点元素
ab // 边(a,b),下同
ad
ae
bc
ce
df
ef
** //输入两个*表示边输入结束
(2)输出图存储结构
如果是邻接矩阵,就按矩阵形式输出,有行、列元素标题。行标题占位4,元素占位6。 如果是加权图,输出边的权值,不存在边则输出“∞“。 如:
Adjacency Matrix is:
a b c d e f
a 0 1 0 1 1 0
b 1 0 1 0 0 0
c 0 1 0 0 1 0
d 1 0 0 0 0 1
e 1 0 1 0 0 1
f 0 0 0 1 1 0
如果是邻接表,先输出顶点元素,再按邻接顺序输出各个邻接点,如果是加权图(边有权值)则用括号把权值括起来。例如输出:
Adjacency List is:
a:–>e–>d–>b
b:–>c–>a
c:–>e–>b
d:–>f–>a
e:–>f–>c–>a
f:–>e–>d
对于有权值图,输出为 a:–>e(3)–>d(10)
(3) 计算各个顶点的度并输出,对有向图要分别计算出度和入度
无向图输出形式为:
Degree of Vertex:
Degree(a)=3
Degree(b)=2

有向图输出形式为:
Degree of Vertex:
Degree(a)=6
Out_Degree(a)=2;In_Degree(a)=4
Degree(b)=2
Out_Degree(b)=2;In_Degree(b)=0

(4) 深度遍历
输入:遍历开始的顶点
输出: 先换行,再输出"Depth-First Traversal order:" ,后面是深度遍历得到的顶点元素序列。
例如:Depth-First Traversal order:abcde
(5) 广度遍历
输入:遍历开始的顶点
输出:先换行,再输出 “Breadth-First Traversal order:”,后面是广度遍历得到的顶点元素序列。
例如:Breadth-First Traversal order:abcde
例如,下面是一个测试用例:
1 //选择存储结构,邻接矩阵
1 //选择操作,创建图
1 //图类型,无向无权图
6 //顶点个数
abcdef //输入顶点元素
ab //输入一条边(a,b)
ad
ae
bc
ce
df
ef
** //边输入结束
2 //输出存储结构
3 //计算图顶点的度
0 //结束
例如:
输入

1
1
1
6
abcdef
ab
ad
ae
bc
ce
df
ef
**
2
3
0

输出


Adjacency Matrix is:
         a     b     c     d     e     f
   a     0     1     0     1     1     0
   b     1     0     1     0     0     0
   c     0     1     0     0     1     0
   d     1     0     0     0     0     1
   e     1     0     1     0     0     1
   f     0     0     0     1     1     0

Degree of Vertex:
Degree(a)=3
Degree(b)=2
Degree(c)=2
Degree(d)=2
Degree(e)=3
Degree(f)=2

输入

2
1
3
5
abcde
ab3
ad2
ae10
bc4
bd8
cd3
ce5
de1
**0
2
3
4
d
5
a
0

输出


Adjacency List is:
a:-->e(10)-->d(2)-->b(3)
b:-->d(8)-->c(4)-->a(3)
c:-->e(5)-->d(3)-->b(4)
d:-->e(1)-->c(3)-->b(8)-->a(2)
e:-->d(1)-->c(5)-->a(10)

Degree of Vertex:
Degree(a)=3
Degree(b)=3
Degree(c)=3
Degree(d)=4
Degree(e)=3

Depth-First Traversal order:decba

Breadth-First Traversal order:aedbc
#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;
const int maxSize=505;
int visit[505];//记录访问的元素
template<class T>
class Queue//队列ADT
{
    
    
private:
    T a[maxSize];
    int head,tail;
public:
    Queue(){
    
    head=0;tail=0;}
    void Push(T x){
    
    a[tail]=x;tail=(tail+1)%maxSize;}
    void Pop(){
    
    head=(head+1)%maxSize;}
    T Front(){
    
    return a[head];}
    T Back(){
    
    return a[tail-1];}
    int Size(){
    
    return (tail-head+maxSize)%maxSize;}
    bool Empty(){
    
    return head==tail;}
};
Queue<int>q;
class graph//图ADT
{
    
    
private:
    int ver[505];//根据字符确定位置
    int g1[505][505];//邻接矩阵
    int len;//顶点个数
    int dir;//是否有向:1表示有向,2表示无向
    int wei;//是否加权:1表示不加权,2表示加权
    int sto;//存储类型:1表示邻接矩阵,2表示邻接表
    int d[505];//各个结点的度
    int in_d[505];//各个结点的入度
    int out_d[505];//各个结点的出度
    char elements[505];//所有的结点
public:
    void Init();
    void create(int d1,int w,int s);
    void show();//输出存储结构
    void showDeg();//输出各顶点的度
    void show_dfs();//输出dfs结果
    void BFS();//输出bfs结果
    void DFS(int x);//深度度遍历
};
void graph::Init()
{
    
    
    for(int i=1;i<=500;i++)
        for(int j=1;j<=500;j++)g1[i][j]=0;
    for(int i=1;i<=500;i++)
    {
    
    
        d[i]=0;
        in_d[i]=0;
        out_d[i]=0;
    }
}
void graph::create(int d1,int w,int s)
{
    
    
    Init();
    dir=d1;
    wei=w;
    sto=s;
    int i,weight,x,y;
    char e[10];
    scanf("%d",&len);
    scanf("%s",elements+1);
    for(i=1;i<=len;i++)
    {
    
    
        ver[(int)elements[i]]=i;//字符对应的索引
    }
    while(scanf("%s",e)!=EOF&&e[0]!='*')
    {
    
    
        x=ver[(int)e[0]];
        y=ver[(int)e[1]];
        if(wei==1)//不加权
        {
    
    
            if(dir==1)//有向
            {
    
    
                g1[x][y]=1;
                out_d[x]++;
                in_d[y]++;
                d[x]++;
                d[y]++;
            }
            else if(dir==2)//无向
            {
    
    
                g1[x][y]=1;
                g1[y][x]=1;
                d[x]++;
                d[y]++;
            }
        }
        else if(wei==2)//加权
        {
    
    
            weight=0;
            for(int i=2;e[i]!='\0';i++)weight=weight*10+e[i]-'0';//权不一定是一位
            if(dir==1)
            {
    
    
                g1[x][y]=weight;
                out_d[x]++;
                in_d[y]++;
                d[x]++;
                d[y]++;
            }
            else if(dir==2)
            {
    
    
                g1[x][y]=weight;
                g1[y][x]=weight;
                d[x]++;
                d[y]++;
            }
        }
    }
}
void graph::show()
{
    
    
    if(sto==1)//邻接矩阵
    {
    
    
        printf("Adjacency Matrix is:\n");
        printf("    ");
        for(int i=1;i<=len;i++)printf("%6c",elements[i]);
        printf("\n");
        for(int i=1;i<=len;i++)
        {
    
    
            printf("%4c",elements[i]);
            for(int j=1;j<=len;j++)
            {
    
    
                if(wei==1)printf("%6d",g1[i][j]);
                else if(wei==2)
                {
    
    
                    if(i!=j&&g1[i][j]==0)printf("     ∞");//有权图中权
                    else printf("%6d",g1[i][j]);
                }
            }
            printf("\n");
        }
    }
    else if(sto==2)//邻接表
    {
    
    
        printf("Adjacency List is:\n");
        for(int i=1;i<=len;i++)
        {
    
    
            printf("%c:",elements[i]);
            for(int j=len;j>=1;j--)
            {
    
    
                if(g1[i][j]!=0)
                {
    
    
                    if(wei==1)printf("-->%c",elements[j]);
                    else if(wei==2)printf("-->%c(%d)",elements[j],g1[i][j]);
                }
            }
            printf("\n");
        }
    }
}
void graph::showDeg()
{
    
    
    printf("Degree of Vertex:\n");
    if(dir==1)
    {
    
    
        for(int i=1;i<=len;i++)
        {
    
    
            printf("Degree(%c)=%d\n",elements[i],d[i]);
            printf("Out_Degree(%c)=%d;In_Degree(%c)=%d\n\n",elements[i],out_d[i],elements[i],in_d[i]);
        }
    }
    else if(dir==2)
    {
    
    
        for(int i=1;i<=len;i++)printf("Degree(%c)=%d\n",elements[i],d[i]);
    }
}
void graph::show_dfs()
{
    
    
    char poi[5];
    scanf("%s",poi);
    for(int i=1;i<=len;i++)visit[i]=0;
    int start=ver[(int)poi[0]];
    printf("Depth-First Traversal order:");
    for(int i=start;i<=len;i++)if(visit[i]==0)DFS(i);//从当前结点遍历到最后
    for(int i=1;i<=start-1;i++)if(visit[i]==0)DFS(i);//从第一个结点遍历到当前结点
    printf("\n");
}
void graph::DFS(int x)
{
    
    
    printf("%c",elements[x]);
    visit[x]=1;
    if(sto==1)
        for(int i=1;i<=len;i++)
        {
    
    
            if(g1[x][i]!=0&&visit[i]==0)DFS(i);
        }
    else if(sto==2)
        for(int i=len;i>=1;i--)
        {
    
    
            if(g1[x][i]!=0&&visit[i]==0)DFS(i);
        }
}
void graph::BFS()
{
    
    
    char poi[5];
    scanf("%s",poi);
    for(int i=1;i<=len;i++)visit[i]=0;
    int start=ver[(int)poi[0]];
    visit[start]=1;
    q.Push(start);
    printf("Breadth-First Traversal order:");
    int t;
    if(sto==1)
    {
    
    
        while(!q.Empty())//借助队列完成广度遍历
        {
    
    
            t=q.Front();
            q.Pop();
            printf("%c",elements[t]);
            for(int i=1;i<=len;i++)//邻接矩阵从前往后
            {
    
    
                if(g1[t][i]!=0&&visit[i]==0)
                {
    
    
                    q.Push(i);
                    visit[i]=1;
                }
            }
        }
    }
    else if(sto==2)
    {
    
    
        while(!q.Empty())
        {
    
    
            t=q.Front();
            q.Pop();
            printf("%c",elements[t]);
            for(int i=len;i>=1;i--)//邻接表从后往前
            {
    
    
                if(g1[t][i]!=0&&visit[i]==0)
                {
    
    
                    q.Push(i);
                    visit[i]=1;
                }
            }
        }
    }
}
graph g;
int main()
{
    
    
    int storage,kind,op;
    scanf("%d",&storage);
    if(storage==1)
    {
    
    
        while(1)
        {
    
    
            scanf("%d",&op);
            switch(op)
            {
    
    
            case 0:
                exit(0);
            case 1:
                scanf("%d",&kind);
                if(kind==1)g.create(2,1,1);//无向,不加权
                else if(kind==2)g.create(1,1,1);//有向,不加权
                else if(kind==3)g.create(2,2,1);//无向,加权
                else if(kind==4)g.create(1,2,1);//有向,加权
                break;
            case 2:
                printf("\n");
                g.show();
                break;
            case 3:
                printf("\n");
                g.showDeg();
                break;
            case 4:
                printf("\n");
                g.show_dfs();
                break;
            case 5:
                printf("\n");
                g.BFS();
                break;
            }
        }
    }
    else if(storage==2)
    {
    
    
        while(1)
        {
    
    
            scanf("%d",&op);
            switch(op)
            {
    
    
            case 0:
                exit(0);
            case 1:
                scanf("%d",&kind);
                if(kind==1)g.create(2,1,2);//无向,不加权
                else if(kind==2)g.create(1,1,2);//有向,不加权
                else if(kind==3)g.create(2,2,2);//无向,加权
                else if(kind==4)g.create(1,2,2);//有向,加权
                break;
            case 2:
                printf("\n");
                g.show();
                break;
            case 3:
                printf("\n");
                g.showDeg();
                break;
            case 4:
                printf("\n");
                g.show_dfs();
                break;
            case 5:
                printf("\n");
                g.BFS();
                break;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/upc122/article/details/106175421