图的广度优先遍历BFS·邻接表方法

图的广度优先遍历

题目信息

程序的输入是无向图的顶点序列和边序列(顶点序列以*为结束标志,边序列以-1,-1为结束标志)。程序的输出为图的邻接表和广度优先遍历序列。例如测试样例

测试样例

a
b
c
d
e
f
*
0,1
0,4
1,4
1,5
2,3
2,5
3,5
-1,-1
the ALGraph is
a 4 1
b 5 4 0
c 5 3
d 5 2
e 1 0
f 3 2 1
the Breadth-First-Seacrh list:aebfdc

解答

#include <iostream>

using namespace std;

typedef struct list
{
    
    
    char ch;
    int number, visited;
    struct list *next;
} List;

List *head[100];

int CreateList()
{
    
    
    int count = 0;
    char ch;
    List *p;
    while (1)
    {
    
    
        cin >> ch;
        if (ch == '*')
        {
    
    
            break;
        }
        else
        {
    
    
            p = new List;
            p->number = count;//用number来记录当前存在数组里的第几个位置
            p->next = NULL;
            p->visited = 0;
            p->ch = ch;
            head[count++] = p;
        }
    }

    while (1)
    {
    
    
        int x, y;
        char chtmp;
        cin >> x >> chtmp >> y;
        if (x == -1 && y == -1)
        {
    
    
            break;
        }
        else
        {
    
    
            p = new List;//新建一个节点
            p->number = y;//y作为他的number值
            p->ch = head[p->number]->ch;//此时的节点的字母定位到之前存好的字母
            p->visited = 0;//没有遍历过这个点
            if (head[x]->next == NULL)
            {
    
    //head后面无续上的链表
                p->next = NULL;
            }
            else
            {
    
    
                p->next = head[x]->next;
            }
            head[x]->next = p;//将这个点续到head这个数组元素后面

            p = new List;
            p->number = x;
            p->ch = head[p->number]->ch;
            p->visited = 0;
            if (head[y]->next == NULL)
            {
    
    
                p->next = NULL;
            }
            else
            {
    
    
                p->next = head[y]->next;
            }
            head[y]->next = p;
        }
    }

    return count;
}

void Print(int count)
{
    
    
    List *p;
    for (int i = 0; i < count; i++)
    {
    
    
        cout << head[i]->ch;
        p = head[i]->next;
        while (p != NULL)
        {
    
    
            cout << " " << p->number;
            p = p->next;
        }
        cout << endl;
    }
}

void BFS(int count)
{
    
    
    int queue[count];//用数组而不用队列的原因是,在遍历结束后需要对路径上的点进行输出,所以需要用数组记录下遍历的路径
    int first = 0, last = 0;
    for (int i = 0; i < count; i++)
    {
    
    //此处的循环的意思是若有非联通的点也会被考虑上
        if (head[i]->visited == 0)
        {
    
    
            for (int j = 0; j < count; j++)
            {
    
    
                queue[j] = -1;
            }
            first = 0;
            last = 0;
            queue[0] = i;
            head[i]->visited = 1;
            last++;
            //大层的while是用来对能连通的点进行进一步操作
            //小层的while是用来找到当前第一个点的子节点
            while (first != last)
            {
    
    //此处开始其实才是真正的bfs的阶段
                List *p = head[queue[first]]->next;
                while (p != NULL)
                {
    
    //不断遍历来找相通的点
                    if (head[p->number]->visited == 0)
                    {
    
    
                        queue[last] = p->number;
                        head[p->number]->visited = 1;
                        last++;
                    }
                    p = p->next;
                }
                first++;
            }

            int j = 0;
            cout << head[queue[j++]]->ch;
            while (queue[j] != -1 && j < count)
            {
    
    
                cout << head[queue[j++]]->ch;
            }
        }
    }
    cout << endl;
}

int main()
{
    
    
    //freopen("/Users/zhj/Downloads/test.txt", "r", stdin);
    int count = CreateList();//count记录着有多少个点
    cout << "the ALGraph is" << endl;
    Print(count);
    cout << "the Breadth-First-Seacrh list:";
    BFS(count);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhj12399/article/details/109707983