图的基本adt实现

假设图的数据元素类型为字符,采用邻接表存储。请编程实现下列操作:
(1) 创建图。用户可以选择创建图的类型,根据类型输入有关信息;
(2)插入顶点
(3)删除顶点
(4)插入边
(5)删除边
(6)深度遍历

(7)广度遍历

#include <iostream>
#include <string>
#include <math.h>
#include <stdio.h>
#include <queue>
using namespace std;
struct linkNode//存储邻接点信息
{
    int loc;
    int weight;
    linkNode *next;
    linkNode(int location,int cost):loc(location),weight(cost),next(NULL) { }
};
struct VNode//存储元素
{
    char vertex;
    linkNode *next;
};
class Graph
{
private:
    int type;
    VNode *table;
    int VNum;
    int ENum;
    int maxV;
public:
    void setType(int i)
    {
        type = i;
    }
    int getType()
    {
        return type;
    }
    Graph(int sz=10)//构造函数
    {
        table = new VNode[sz];
        if(table==NULL) cout<<"分配出错"<<endl;
        for(int i = 0; i<sz; i++) table[i].next =NULL;
        VNum = 0;
        ENum = 0;
        maxV = sz;
    }
    ~Graph()//析构函数
    {
        for(int i = 0; i < VNum; i++)
        {
            linkNode *p =table[i].next;
            while(p != NULL)
            {
                table[i].next = p->next;
                delete p;
                p = table[i].next;
            }
        }
        delete [ ]table;  		     //删除顶点表数组
    }
    int getVPos(char v)//得到点的位置
    {
        for(int i=0; i<VNum; i++)
        {
            if(table[i].vertex==v)return i;
        }
        return -1;
    }
    char getVlue(int i)//由位置得到点
    {
        if(i<VNum)return table[i].vertex;
        else return '\0';
    }
    char getFirstNeighbor(char v)//得到第一个邻居
    {
        int pos = getVPos(v);
        if(pos==-1)return '\0';
        else
        {
            if(table[pos].next!=NULL)return getVlue(table[pos].next->loc);
            else return '\0';
        }
    }
    char getNextNeighbor (char v, char w)//得到w后的邻居
    {
        int pos1 = getVPos(v);
        int pos2 = getVPos(w);
        if(pos1 !=-1 && pos2 !=-2)
        {
            linkNode *temp = table[pos1].next;
            while(temp!=NULL)
            {
                if(temp->loc==pos2)
                {
                    if(temp->next==NULL) return '\0';
                    return getVlue(temp->next->loc);
                }
                else temp = temp->next;
            }
        }
        return '\0';
    }
    bool insertV(char v)//插入顶点
    {
        if(VNum<maxV)
        {
            table[VNum].vertex = v;
            VNum++;
            return true;
        }
        return false;
    }
    bool deleteV(char v)//删除顶点
    {
        int i = getVPos(v);
        if(v==-1)return false;
        else
        {
            linkNode *temp = table[i].next;
            while(temp!=NULL)
            {
                table[i].next = temp->next;
                delete temp;
                temp = table[i].next;
            }
            for(int j = i; j<VNum-1; j++) table[j] = table[j+1];
            VNum--;
            return true;
        }
    }
    bool insertEdge(char v1,char v2,int cost)//插入边
    {
        int p1 = getVPos(v1);
        int p2 = getVPos(v2);
        if(p1 !=-1 && p2!=-1)
        {
            if(table[p1].next==NULL)
            {
                table[p1].next=new linkNode(p2,cost);
            }
            else
            {
                linkNode *temp = table[p1].next;
                while(temp->next!=NULL)
                {
                    temp = temp->next;
                }
                temp->next = new linkNode(p2,cost);
            }
            return true;
        }
        else return false;

    }
    bool deleteEdge(char v1,char v2)//删除边
    {
        int i = getVPos(v1);
        int j = getVPos(v2);
        if(table[i].next!=NULL)
        {
            if(table[i].next->loc==j)
            {
                linkNode *temp = table[i].next;
                table[i].next = temp->next;
                delete temp;
                return true;
            }
            else
            {
                linkNode *node = table[i].next;
                linkNode *temp = table[i].next->next;
                while(temp!=NULL)
                {
                    if(temp->loc==j)
                    {
                        node->next = temp->next;
                        delete temp;
                        return true;
                    }
                    else
                    {
                        node = temp;
                        temp = temp->next;
                    }
                }
                return false;
            }
        }
        return false;

    }
    void DFS(char v, bool visited[])//以某一顶点开始的深度遍历
    {
        cout<<"->"<<v;
        int i = getVPos(v);
        visited[i] = true;
        char w = getFirstNeighbor(v);
        int j = getVPos(w);
        while(j!=-1)
        {
            if(!visited[j])DFS(w,visited);
            w = getNextNeighbor(v,w);
            j = getVPos(w);
        }
    }
    void DFS_Graph()//深度遍历
    {
        bool *visited = new bool[VNum];
        for(int i = 0; i<VNum; i++) visited[i] = false;
        for(int i=0; i<VNum; i++)
        {
            if(!visited[i])DFS(table[i].vertex,visited);
        }
        delete [] visited;
        cout<<endl;
    }
    void BFS ()//广度遍历
    {
        if(VNum==0) return ;
        char v = table[0].vertex;
        bool *visited = new bool[VNum];
        for(int i = 0; i<VNum; i++) visited[i] = false;
        cout<<"->"<<v;
        int j = 0;
        visited[j] = true;
        queue<char> q;
        q.push(v);
        char w;
        while(!q.empty())
        {
            v = q.front();
            q.pop();
            w = getFirstNeighbor(v);
            j = getVPos(w);
            while(j!=-1)
            {
                if(!visited[j])
                {
                    cout<<"->"<<w;
                    visited[j]=true;
                    q.push(w);
                }
                w = getNextNeighbor(v,w);
                j = getVPos(w);
            }
        }
        cout<<endl;
    }
};
void show(Graph &g)
{

    cout<<"*****************"<<endl;
    cout<<"[1]插入顶点"<<endl;
    cout<<"[2]插入边"<<endl;
    cout<<"[3]删除顶点"<<endl;
    cout<<"[4]删除边"<<endl;
    cout<<"[5]以顶点V1开始的广度遍历"<<endl;
    cout<<"[6]深度遍历"<<endl;
    cout<<"*****************"<<endl;
    int i;
    cin>>i;
    getchar();
    char c,c1,c2;
    switch(i)
    {
    case 1:
        cout<<"请输入定点的值,字符型变量"<<endl;
        cin>>c;
        g.insertV(c);
        break;
    case 2:
        cout<<"请输入两个顶点上的值,字符型变量"<<endl;
        cin>>c1>>c2;
        if(g.getType()) g.insertEdge(c1,c2,1);
        else
        {
            g.insertEdge(c1,c2,1);
            g.insertEdge(c2,c1,1);
        }
        break;
    case 3:
        cout<<"请输入定点的值,字符型变量"<<endl;
        cin>>c;
        g.deleteV(c);
        break;
    case 4:
        cout<<"请输入两个顶点上的值,字符型变量"<<endl;
        cin>>c1>>c2;
        if(g.getType()) g.deleteEdge(c1,c2);
        else
        {
            g.deleteEdge(c1,c2);
            g.deleteEdge(c2,c1);
        }
        break;
    case 5:
        g.BFS();
        break;
    case 6:
        g.DFS_Graph();
        break;
    default:
        break;
    }
}
int main()
{
    int n;
    cout<<"请输入顶点个数的最大值"<<endl;
    cin>>n;
    Graph g(n);
    cout<<"请输入1或0,1表示有向图,0表示无向图"<<endl;
    int i;
    cin>>i;
    if(i==1 || i==0)g.setType(i);
    else
    {
        cout<<"输入有误";
        return 0;
    }
    for(;;)
    {
        show(g);
    }
    return 0;
}

欢迎评论!

猜你喜欢

转载自blog.csdn.net/baidu_38370610/article/details/73555754
ADT
今日推荐