图的表示

邻接矩阵

相连的标1,不相连的为0:

snipaste_20181119_232224.png

  1. #ifndef GRAPHVERTEX_H
  2. #define GRAPHVERTEX_H
  3. #include <iostream>
  4. //节点
  5. class Vertex
  6. {
  7. public:
  8. Vertex(char lab):lab(lab){}
  9. private:
  10. char lab;
  11. };
  12. //图
  13. class Graph
  14. {
  15. public:
  16. Graph();
  17. ~Graph();
  18. void addVertex(char lab);
  19. void addEdge(int start, int end);
  20. void printMatrix();
  21. private:
  22. Vertex* list[20]; //保存图的每个节点
  23. int num; //节点个数
  24. int Mat[20][20]; //邻接矩阵
  25. };
  26. Graph::Graph()
  27. {
  28. num = 0;
  29. for (int i = 0; i < 20; i++)
  30. for (int j = 0; j < 20; j++)
  31. Mat[i][j] = 0;
  32. }
  33. Graph::~Graph()
  34. {
  35. for (int i = 0; i < num; i++)
  36. delete list[i];
  37. }
  38. void Graph::addVertex(char lab)
  39. {
  40. list[num++] = new Vertex(lab);
  41. }
  42. void Graph::addEdge(int start, int end)
  43. {
  44. //对称,A-B和B-A都要置1
  45. Mat[start][end] = 1;
  46. Mat[end][start] = 1;
  47. }
  48. void Graph::printMatrix()
  49. {
  50. for (int i = 0; i < num; i++)
  51. {
  52. for (int j = 0; j < num; j++)
  53. std::cout<<Mat[i][j]<<" ";
  54. std::cout<<std::endl;
  55. }
  56. }
  57. #endif // GRAPHVERTEX_H

邻接表

snipaste_20181120_204205.png

  1. #ifndef GRAPHTABLE_H
  2. #define GRAPHTABLE_H
  3. #include <list>
  4. #include <iostream>
  5. //图
  6. template<typename T>
  7. class Graph
  8. {
  9. public:
  10. Graph(const int num):n(num)
  11. {
  12. vertexList = new T*[n];
  13. headNodes = new std::list<int>[n];//一个节点对应一个链表
  14. nVerts = 0;
  15. }
  16. ~Graph()
  17. {
  18. delete [] vertexList;
  19. delete [] headNodes;
  20. }
  21. void addVertex(T* lab);
  22. void addEdge(int start, int end);
  23. void printNodes();
  24. void printLines();
  25. private:
  26. T** vertexList; //保存所有节点的列表
  27. std::list<int>* headNodes;
  28. int n; //节点个数
  29. int nVerts; //计数用
  30. };
  31. template<typename T>
  32. void Graph<T>::addVertex(T* lab)
  33. {
  34. vertexList[nVerts++] = lab;
  35. }
  36. template<typename T>
  37. void Graph<T>::addEdge(int start, int end)
  38. {
  39. headNodes[start].push_back(end);
  40. headNodes[end].push_back(start);
  41. }
  42. template<typename T>
  43. void Graph<T>::printNodes()
  44. {
  45. for(int i=0; i<nVerts; i++)
  46. std::cout<<*vertexList[i]<<" ";
  47. std::cout<<std::endl;
  48. }
  49. template<typename T>
  50. void Graph<T>::printLines()
  51. {
  52. for(int i=0; i<nVerts; i++)
  53. {
  54. std::cout<<i<<"->";
  55. for(std::list<int>::iterator it=headNodes[i].begin(); it!=headNodes[i].end(); it++)
  56. std::cout<<*it<<"->";
  57. std::cout<<"end"<<std::endl;
  58. }
  59. }
  60. #endif // GRAPHTABLE_H

图的搜索

graphvertex.h

DFS深度优先搜索—>使用栈

从起点开始沿着一条路径走到头,再往回返一个节点,再走另一条路径:

snipaste_20181120_212525.png

  1. //下列代码基于邻接矩阵图,类代码请参考上面代码
  2. void Graph::showVertex(int index)
  3. {
  4. //v为节点下标
  5. std::cout<<list[index]->lab<<" ";
  6. }
  7. int Graph::getNextUnVisitedVertex(int index)
  8. {
  9. for (int i=0; i<num; i++)
  10. {
  11. if(Mat[index][i] == 1 && list[i]->isVisited == false)
  12. return i;
  13. }
  14. return -1;
  15. }
  16. void Graph::DFS()
  17. {
  18. stack<int> gStack;//栈用来保存节点的index
  19. //从0个节点开始显示
  20. list[0]->isVisited = true;
  21. showVertex(0);
  22. gStack.push(0);//将访问过的节点放入栈
  23. int index;
  24. while (gStack.size() > 0)
  25. {
  26. index = getNextUnVisitedVertex(gStack.top());
  27. if (index == -1)
  28. {
  29. gStack.pop();//往回返一个节点,删除当前
  30. }
  31. else
  32. {
  33. list[index]->isVisited = true;
  34. showVertex(index);
  35. gStack.push(index);
  36. }
  37. }
  38. for(int i=0; i<num; i++)
  39. list[i]->isVisited = false;//还原记得状态
  40. }

BFS广度优先搜索—>使用队列

从起点开始,遍历所有与该节点相连的节点,一次往后:

snipaste_20181120_212640.png

void Graph::BFS()
{
    queue<int> gQueue;//保存访问过的节点index
    //从0个节点开始显示
    list[0]->isVisited = true;
    showVertex(0);
    gQueue.push(0);//将访问过的节点放入栈

    int index;
    while (gQueue.size() > 0)
    {
        index = getNextUnVisitedVertex(gQueue.front());
        while (index != -1)
        {
            //找出当前节点所有关联节点,放入队列
            list[index]->isVisited = true;
            showVertex(index);
            gQueue.push(index);
            index = getNextUnVisitedVertex(gQueue.front());
        }

        gQueue.pop();//删除当前节点,因为已经show
    }

    for(int i=0; i<num; i++)
        list[i]->isVisited = false;//还原记得状态
}