图的存储方式及实现

图的存储方式及实现

邻接矩阵法

  • 图类的各元素

    class MGraph //有向图
    {
    private:
        int Ne;              //边数
        int N;               //结点数
        int Graph[Max][Max]; //二维矩阵
        char Node[Max];      //结点值
    public:
        MGraph(char a[], int n, int e);
        void display();
        void getOutNum(); //出度
        void getInNum();  //入度
    };
    
  • 初始化图

    MGraph::MGraph(char a[], int n, int e)
    {
        Ne = e;
        N = n;
    
        //给结点赋值
        for (int i = 0; i < N; i++)
        {
            Node[i] = a[i];
        }
    
        //输入边并赋值
        memset(Graph, 0, sizeof(Graph));
        int i, j;
        for (int k = 0; k < e; k++)
        {
            cin >> i >> j;
            Graph[i][j] = 1; //有向图且无权值
            // Graph[j][i] = 1; //无向图
        }
    }
    
  • 展示函数

    void MGraph::display()
    {
        cout << "输出各结点的值"
             << "\n";
        for (int i = 0; i < N; i++)
        {
            cout << Node[i] << " ";
        }
        cout << "\n"
             << "输出邻接矩阵"
             << "\n";
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                cout << Graph[i][j] << " ";
            }
            cout << "\n";
        }
    }
    
  • 入度及出度

void MGraph::getOutNum()
{
    cout << endl;
    for (int i = 0; i < N; i++)
    {
        int num = 0;
        for (int j = 0; j < N; j++)
        {
            if (Graph[i][j] != 0)
            {
                num++;
            }
        }
        cout << "第" << i << "个结点的出度为:" << num << endl;
    }
}

void MGraph::getInNum()
{
    cout << endl;
    for (int i = 0; i < N; i++)
    {
        int num = 0;
        for (int j = 0; j < N; j++)
        {
            if (Graph[j][i] != 0)
            {
                num++;
            }
        }
        cout << "第" << i << "个结点的入度为:" << num << endl;
    }
}

邻接表法

  • 结点数组,数组中的任一元素指向一链表,表示指向的结点

    struct Edge		//链表的结点
    {
        Edge *next; //指向下一个结点
        int p;      //结点对应的下标
    };
    
    struct Node		//数组元素
    {
        char val;
        Edge *first; //每个结点串一条链表,为指出的
    };
    
  • 图类各元素

    class LGraph
    {
    private:
        Node node[Max]; //头结点的数组
        int N, Ne;
    
    public:
        LGraph(char a[], int n, int e);
        void display();
        void getInNum();
        void getOutNum();
    };
    
  • 初始化图

    LGraph::LGraph(char a[], int n, int e)
    {
        N = n;
        Ne = e;
    
        //结点赋值
        for (int i = 0; i < N; i++)
        {
            node[i].val = a[i];
            node[i].first = NULL;
        }
    
        //连接
        char z, b;
        for (int k = 0; k < Ne; k++)
        {
            cin >> z >> b;
            for (int i = 0; i < N; i++)
            {
                if (z == node[i].val)
                { //找到要插入的头
                    Edge *e = new Edge;
                    // e->p = k;
                    for (int j = 0; j < N; j++)
                    { //找到结点的值对应的下标
                        if (b == node[j].val)
                        {
                            e->p = j;
                            break;
                        }
                    }
                    e->next = node[i].first;
                    node[i].first = e;
                    break;
                }
            }
        }
    }
    
  • 展示函数,需要注意的是,遍历时需要创建一个临时变量来代替first指针,否则first最终将指向链表最后一个元素的后面

    void LGraph::display()
    {
        cout << "输出各结点及其指向的其他结点"
             << "\n";
        for (int i = 0; i < N; i++)
        {
            Edge *o = node[i].first; //防止头指针被改变
            cout << node[i].val << " ";
            while (o != NULL)
            {
                cout << o->p << " ";
                o = o->next;
            }
            cout << endl;
        }
    }
    
  • 入度及出度:first指针的处理同上

    void LGraph::getOutNum()
    {
        cout << endl;
        for (int i = 0; i < N; i++)
        {
            int num = 0;
            Edge *o = node[i].first; //防止头指针被改变
            while (o != NULL)
            {
                num++;
                o = o->next;
            }
            cout << node[i].val << "的结点的出度为:" << num << endl;
        }
    }
    
    void LGraph::getInNum()
    {
        cout << endl;
        int x[N]; //用以存储各结点的入度
        memset(x, 0, sizeof(x));
        for (int i = 0; i < N; i++)
        {
            while (node[i].first != NULL)
            {
                x[node[i].first->p]++;
                node[i].first = node[i].first->next;
            }
        }
        for (int i = 0; i < N; i++)
        {
            cout << node[i].val << "的结点的入度为:" << x[i] << endl;
        }
    }
    
posted @ 2022-05-09 21:07  laterya  阅读(92)  评论(0)    收藏  举报