图的深度优先遍历,基于邻接链表的非递归实现

来源:互联网 发布:如何下载图片源码 编辑:程序博客网 时间:2024/05/07 08:01


测试数据基于上图,新增4->1的路径。程序存在内存泄漏。

使用时可以修改depth_first_search第二个参数,指定开始遍历的结点,只适用与连通图。如果错误,欢迎指正!!

#include <iostream>

#include <stack>


using namespace std;


/***************************************
 * 图的深度优先遍历
 * 基于邻接链表的非递归实现
 **************************************/


typedef char vertex_t;  //结点数据类型


//边结点
typedef struct _tag_edge_node_t
{
    int node_num;  //边终点所在数组序号
    _tag_edge_node_t* next_node;  //下一条边
}edge_node_t;


//顶点结点
typedef struct _tag_head_node_t
{
    vertex_t data;  //结点数据
    edge_node_t* first_edge;  //第一条边
}head_node_t;


#define MAX_NUMBER 20  //图中最大结点数目


//图结构
typedef struct _tag_graph_t
{
    head_node_t head_data[MAX_NUMBER];  //顶点数组
    unsigned int head_node_count;  //顶点数目
}graph_t;


void create_adjacency_list(graph_t* graph)
{
    edge_node_t* p_edge = NULL;
    if (graph == NULL)
        return;


    graph->head_node_count = 6;
    for (unsigned int i = 0; i < graph->head_node_count; ++i)
    {
        graph->head_data[i].data = 'A' + i;
        graph->head_data[i].first_edge = NULL;
    }


    graph->head_data[0].first_edge = new edge_node_t;
    p_edge = graph->head_data[0].first_edge;
    p_edge->node_num = 2;
    
    p_edge->next_node = new edge_node_t;
    p_edge = p_edge->next_node;
    p_edge->node_num = 4;


    p_edge->next_node = new edge_node_t;
    p_edge = p_edge->next_node;
    p_edge->node_num = 5;
    p_edge->next_node = NULL;


    graph->head_data[1].first_edge = new edge_node_t;
    graph->head_data[1].first_edge->node_num = 2;
    graph->head_data[1].first_edge->next_node = NULL;


    graph->head_data[2].first_edge = new edge_node_t;
    graph->head_data[2].first_edge->node_num = 3;
    graph->head_data[2].first_edge->next_node = NULL;


    graph->head_data[3].first_edge = new edge_node_t;
    graph->head_data[3].first_edge->node_num = 5;
    graph->head_data[3].first_edge->next_node = NULL;


    graph->head_data[4].first_edge = new edge_node_t;
    graph->head_data[4].first_edge->node_num = 1;
    graph->head_data[4].first_edge->next_node = 
        new edge_node_t;


    p_edge = graph->head_data[4].first_edge->next_node;
    p_edge->node_num = 3;
    p_edge->next_node = new edge_node_t;


    p_edge = p_edge->next_node;
    p_edge->node_num = 5;
    p_edge->next_node = NULL;
}


void depth_first_search(graph_t* graph, int start_pos)
{
    stack<int> visit_node;
    bool is_visit[MAX_NUMBER];  //访问标志数组
    for (int i = 0; i < MAX_NUMBER; ++i)
        is_visit[i] = false;


    cout<<graph->head_data[start_pos].data<<endl;
    is_visit[start_pos] = true;
    visit_node.push(start_pos);  //将第一个元素压栈
    while (!visit_node.empty())
    {
        int num = visit_node.top();
        edge_node_t* next = graph->head_data[num].first_edge;
        for (; next != NULL; next = next->next_node)  //存在边,且该边的终点未被访问
        {
            if (!is_visit[next->node_num])
            {
            cout<<graph->head_data[next->node_num].data<<endl;
            is_visit[next->node_num] = true;
            visit_node.push(next->node_num);
            break;
            }
        }
        if (next == NULL)  //以该结点为起点的所有终点访问完毕
            visit_node.pop();
    }
}


int main(int argc, char* argv[])
{
    graph_t graph;
    create_adjacency_list(&graph);
    depth_first_search(&graph, 0);
    return 0;

}

0 0
原创粉丝点击