数据结构复习——图的深度优先搜索

1、和树的遍历类似,我们希望从图中某一定点出发访遍图中的其余节点,且每个节点仅被访问一次。

2、实现。

//假定图最多有20个定点
#define MAX_VERTEX_NUM 20
bool visited[MAX_VERTEX_NUM]={false};
//采用邻接链表的方式来存储图中的节点
struct Node
{
    unsigned NodeID_;
    Node* next_;
    Node(unsigned nodeId):
        NodeID_(nodeId),
        next_(nullptr)
    {
    }

    Node()
    {

    }
};

struct Graph
{
    //头定点组成的数组
    Node nodeList[MAX_VERTEX_NUM];
    //定点个数、弧的个数
    int verNum_,arcNum_;

    Graph()
    {
    }
};

//创建采用邻接表存储的图
void createAGraph(Graph& graph)
{
    //假定有5个顶点,6条边
    graph.verNum_=5;
    graph.arcNum_=7;

    for(int i=0;i<graph.verNum_;++i)
    {
        graph.nodeList[i].NodeID_=i;
        graph.nodeList[i].next_=nullptr;
    }
    Node* p2=nullptr;


    for(unsigned i=0;i<5;++i)
    {
        for(unsigned j=0;j<5;++j)
        {
            if(i*j!=4&&i*j!=8&&i*j!=12&&
                    i!=j)
            {
                p2=new Node(j);


                std::cout<<i<<"\t"<<j<<"\t";



                p2->next_=graph.nodeList[i].next_;
                graph.nodeList[i].next_=p2;

            }
        }
        std::cout<<std::endl;
    }
}

void printGraph(Graph& graph)
{
    std::cout<<"输出顶点信息:\n";
    Node* curNode=nullptr;

    for(int i=0;i<graph.verNum_;++i)
    {
        std::cout<<"顶点编号"<<graph.nodeList[i].NodeID_<<std::endl;
        curNode=graph.nodeList[i].next_;

        while(curNode)
        {
            std::cout<<":--->"<<curNode->NodeID_;
            curNode=curNode->next_;
        }
        std::cout<<std::endl;
    }
}

/**
 * @brief firstAdjvex 在图graph中返回顶点编号为adjvexNo对应的邻接表中的首个节点编号
 * @param graph
 * @param adjvexNo
 * @return
 */
int firstAdjvex(Graph& graph,int adjvexNo)
{
    int  firstNodeID=graph.nodeList[adjvexNo].next_->NodeID_;
    return firstNodeID;
}

/**
 * @brief nextAdjvex 在图graph的编号nodeListNo对应的邻接链表中返回
 * 编号为adjvexNo的结点的下一个结点编号
 * @param graph
 * @param nodeListNo
 * @param adjvexNo
 * @return
 */
int nextAdjvex(Graph& graph,unsigned nodeListNo,unsigned adjvexNo)
{
    Node* curNode=graph.nodeList[nodeListNo].next_;

    while(curNode)
    {
        if(curNode->NodeID_==adjvexNo&&curNode->next_!=nullptr)
        {
            return curNode->next_->NodeID_;
        }
        curNode=curNode->next_;
    }
    return -1;
}

//从图graph中以顶点adjvexNo楷书
void DFS(Graph graph,int adjvexNo)
{
    visited[adjvexNo]=true;
    std::cout<<adjvexNo<<"--->\t";
    for(int nextAdjvexNo=firstAdjvex(graph,adjvexNo);nextAdjvexNo>=0;
        nextAdjvexNo=nextAdjvex(graph,adjvexNo,nextAdjvexNo))
    {
        if(visited[nextAdjvexNo]==false)
            DFS(graph,nextAdjvexNo);
    }
}

void DFSTraverse(Graph& graph)
{
    int i=-1;
    for(i=0;i<graph.verNum_;++i)
        visited[i]=false;

    for(i=0;i<graph.verNum_;++i)
    {
        if(visited[i]==false)
            DFS(graph,i);
    }
}




//测试函数
int main()
{
    Graph graph;
    createAGraph(graph);
    printGraph(graph);
    DFSTraverse(graph);
    return 0;
}

3、运行截图。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值