图——广度优先遍历和深度优先遍历——邻接表表示法

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;



struct Edge //边的定义
{ 
    Edge(int i):node(i),nextEdge(NULL){ }
    int node;
    Edge *nextEdge;
};
struct Node //节点的定义
{
    Node(int i):value(i),firstEdge(NULL){}
    int value;
    Edge *firstEdge;
};
struct Figure
{
    vector nodes;//存储节点
    int nodeNums, edgeNums;
};
class Solution {
public:
    //构建表
    void createFigure(Figure &figure)
    {
        //首先输入边的信息
        cout << "请输入节点的数目:" ;
        cin >> figure.nodeNums;
        cout << "请输入边的数目:";
        cin >> figure.edgeNums;
        for (int i = 0; i < figure.nodeNums; ++i) //输入节点信息
        {
            figure.nodes.push_back(new Node(i));
        }
        for (int i = 0; i < figure.nodeNums; ++i)//输入边的信息
        {
            cout << "请输入相关的边:";
            int node1, node2;
            cin >> node1 >> node2;
            auto it = figure.nodes.begin();
            while (it!=figure.nodes.end() && node1!=(*it)->value)
            {
                it++;//找到节点
            }
            if (it != figure.nodes.end())
            {
                //第一种插入方式
                /*Edge* temp = (*it)->firstEdge;
                (*it)->firstEdge = new Edge(node2);
                (*it)->firstEdge->nextEdge = temp;*/
                //第二种插入方式:
                if ((*it)->firstEdge == NULL)
                {
                    (*it)->firstEdge = new Edge(node2);
                }
                else
                {
                    Edge* edge = (*it)->firstEdge;
                    while (edge->nextEdge != NULL)
                    {
                        edge = edge->nextEdge;
                    }
                    edge->nextEdge = new Edge(node2);
                }
                
            }
        }
    }

    void CreateAFigure(Figure &figure)
    {
        figure.nodeNums = 6;
        for (int i = 0; i < figure.nodeNums; ++i) //输入节点信息
        {
            figure.nodes.push_back(new Node(i));
        }
        figure.nodes[0]->firstEdge = new Edge(1);
        figure.nodes[0]->firstEdge->nextEdge = new Edge(2);
        figure.nodes[1]->firstEdge = new Edge(3);
        figure.nodes[1]->firstEdge->nextEdge = new Edge(4);
        figure.nodes[2]->firstEdge = new Edge(3);
        figure.nodes[4]->firstEdge = new Edge(5);
        
    }

    void printFigure(Figure figure)//打印图
    {
        cout << "打印图的结构:" << endl;
        for (int i = 0; i < figure.nodeNums; i++)
        {
            cout <<"v_"<< figure.nodes[i]->value << ": ";
            if (figure.nodes[i]->firstEdge != NULL)
            {
            //  cout << figure.nodes[i]->firstEdge->node << "  ";
                Edge* edge = figure.nodes[i]->firstEdge;
                while (edge!=NULL)
                {
                    cout << "v_"<node << "  ";
                    edge = edge->nextEdge;
                }
            }
            cout << endl;
        }
    }
    //深度优先遍历
    void DFSTraver(Figure figure)
    {
        setVisit(figure);
        for (int i = 0; i < figure.nodeNums; ++i)
        {
            if (visisted[i] == false)//第i个节点没有被访问
                DFS(figure.nodes[i], figure);
        }
    }
    void DFS(Node* node,Figure figure)
    {
        
        if (visisted[node->value] == false)//如果该节点没有被访问过
        {
            cout << "v_" << node->value << "  ";
            visisted[node->value] = true;
        }
        if (node->firstEdge == NULL) return;
        if(visisted[node->firstEdge->node]==false)//第一个边没有被访问,访问第一条边
           DFS(figure.nodes[node->firstEdge->node],figure);
        if (visisted[node->firstEdge->node] == true)//第一个边已经被访问过了,访问第二条没有被访问的边
        {
            //首先找到第一条没有被访问的边
            Edge* edge = node->firstEdge->nextEdge; //第一条可访问的边
            while (edge!=NULL)
            {
                if (visisted[edge->node] == true)//对应的节点已经访问过了
                    edge = edge->nextEdge;
                else
                    break;//对应的节点没有被访问过
            }
            if (edge == NULL) //初始节点对应的边都访问完了
                return;
            else
                DFS(figure.nodes[edge->node], figure);//访问第一条没有访问的边
        }
    }

    //广度优先遍历
    void BFSTravers(Figure figure)
    {
        setVisit(figure);
        for (int i = 0; i < figure.nodeNums; ++i)
        {
            if (visisted[i] == false)
            {
                BFS(figure.nodes[i], figure);
            }
               
        }
    }
    deque parent;
    deque child;
    //此处应该设置两个队列;一个父队列,一个子队列,父亲队列用来存储将要答应的节点,子队列用来存储将要打印的节点
    void BFS(Node* node,Figure figure)
    {
        //if (visisted[node->value] == false)//如果该节点没有被访问过
        //{
        //  cout << "v_" << node->value << "  ";  //打印跟节点
        //  visisted[node->value] = true;
        //}
        //if (node->firstEdge == NULL) return;
        //else
        //{
        //  cout << "v_" << node->firstEdge->node << "  "; //把接下来的根节点存入队列Node中
        //  visisted[node->firstEdge->node] = true;
        //  parent.push(figure.nodes[node->firstEdge->node]);
        //}
        //Edge* edge = node->firstEdge->nextEdge;
        //while (edge!=NULL)
        //{
        //  cout << "v_" << edge->node << "  ";
        //  visisted[node->firstEdge->node] = true;
        //  parent.push(figure.nodes[edge->node]);
        //  edge = edge->nextEdge;
        //}

        child.push_back(node);
        while (!child.empty())
        {
            parent = child;
            child.clear();
            while (!parent.empty())
            {
                
                if (visisted[parent.front()->value] == false)
                {
                    cout << "v_" << parent.front()->value << "  ";  //打印跟节点
                    visisted[parent.front()->value] = true;
                }
                
                Edge* edge = parent.front()->firstEdge;
                while (edge!=NULL)
                {
                    child.push_back(figure.nodes[edge->node]);
                    edge = edge->nextEdge;
                }
                parent.pop_front();
            }
        }
        
        
    }

    vector visisted;//访问过的设置为ture,没访问过设置为false
    void setVisit(Figure figure)
    {
        visisted.clear();
        for (int i = 0; i < figure.nodeNums; i++)
        {
            visisted.push_back(false);
        }
    }
};

int main()
{

    Solution so;
    Figure figure;
    so.CreateAFigure(figure);
    cout << "节点结构:" << endl;;
    so.printFigure(figure);
    cout << "深度优先遍历:";
    so.DFSTraver(figure);
    cout << endl;
    cout << "广度优先遍历:";
    so.BFSTravers(figure);
    cout << endl;
    return 0;
}

转载于:https://www.cnblogs.com/wdan2016/p/6182125.html

你可能感兴趣的:(图——广度优先遍历和深度优先遍历——邻接表表示法)