> 文章列表 > 数据结构与算法基础(王卓)(24):深度优先遍历算法DFS和广度优先遍历算法BFS

数据结构与算法基础(王卓)(24):深度优先遍历算法DFS和广度优先遍历算法BFS

数据结构与算法基础(王卓)(24):深度优先遍历算法DFS和广度优先遍历算法BFS

深度优先遍历算法DFS:

邻接矩阵:

#include<iostream>
using namespace std;typedef int Status;
#define MaxInt 999999  //表示无穷大
#define MVNum 100  //最大顶点数
//MAX Vertex Number
typedef char VertexType;  //设顶点类型:字符型
typedef int ArcType;  //设边的权值类型:int型struct AMG
{VertexType vex[MVNum];  //顶点表ArcType arc[MVNum][MVNum];  //邻接矩阵int VexNum, ArcNum;  //(图)当前:顶点数和边数
};  //Adjacency Matrix Graph//深度优先遍历算法(邻接矩阵)
int visited[MVNum] = {};    //未访问时元素全部为空void DFS(AMG G, int v)
{int w;//访问第v个结点cout << G.vex[v]; //输出顶点内容//cout << v << endl;visited[v] = 1;//依次检查邻接矩阵v所在的行for (w = 0; w < G.VexNum; w++)//从邻接矩阵的第v行的第1个元素开始-遍历到该行第n个元素{if ((G.arc[v][w] != 0) && !visited[w])//相连且未被访问过DFS(G, w);}//算法时间复杂度O(n^2)
}int main()
{}

邻接表:

一开始我写的(第一版):

void DFS(ALG G, int v)
{int w,i=0;ArcNode* p=G.vex->firstarc;//访问第v个结点while (i < v){p = p->nextarc;i++;}cout << p->adjvex; //输出顶点内容位置visited[v] = 1;//依次检查邻接矩阵v所在的行for (w = 0; w < G.vexnum; w++)//从邻接矩阵的第v行的第1个元素开始-遍历到该行第n个元素{p = p->nextarc;if ((p->adjvex) && !visited[w])
//        if ((G.vex[v][w] != 0) && !visited[w])//相连且未被访问过DFS(G, w);}  
}

这里,我们犯(陷入)了许多个逻辑错误

问题:

(1):

我们写的函数:在一开始指向的,并不是第 i 个顶点,而是第一个顶点的第 i 个元素

更何况我们第一步要输出的,是一个顶点,而非一个边结点

(2):

在最后的判断语句最好还是新设立一个指针变量,要不然后面我感觉p容易变混乱了

 哈哈哈扯淡的,后面其实根本不需要这个玩意 


最终成品:

//深度优先遍历算法
int visited[MVNum] = {};    //未访问时元素全部为空
void DFS(ALG G, int v)
{int w,i=0;cout << G.vex[v].data; visited[v] = 1;ArcNode* p = G.vex[v].firstarc;while (p != NULL){if (visited[p->adjvex] != 0)DFS(G,p->adjvex);p = p->nextarc;}
}

By the way,复习一下链表【取第i个元素】:

Status 取第i个元素(LinkList L, int i, Elemtype e)
{// GetElem“i”
    LinkList p;
    p = L->next;
    int j = 1;
    while (p && i > j)
    {
        p = p->next;
        j++;
    }
    if (i < 0 || i < j || !p)
        return false;
    e = p->data;
    return true;
}


广度优先遍历算法BFS

breadth:宽度;(知识、兴趣等的)广泛

邻接表:


我写的:

int visited[MVNum] = {};    
void BFS(ALG G, int v)
{cout << G.vex[v].data;visited[v] = 1;SqQueue Q;InitQueue(Q);EnQueue(Q, G.vex[v].firstarc->adjvex);//从第一个顶点开始遍历auto i = G.vex[v].firstarc;//指向(代表)链头while (!QueneEmpty(Q))//直至队空结束{auto j = i;//用于指向访问各个元素节点while (j != NULL)//当结点为空(链尾,结束了)结束循环{if (visited[j->adjvex] == 0)//入队【没被访问过的】元素{EnQueue(Q, j->adjvex);}j = j->nextarc;//指向下一轮循环visited[j->adjvex] = 1;//别忘了}DeQueue(Q, i->adjvex);//出队队头cout << j->adjvex;//输出出队的元素,当然这里出队和输出在循环开始时操作也可以}
}

详细学习过程以及整个过程中所有踩的坑,详见:

数据结构与算法基础(王卓)(24)附:邻接表的广度优先遍历算法BFS(学习过程记录)_宇 -Yu的博客-CSDN博客


邻接矩阵:

void BFS(AMG& G)
{for (int v = 0; v < G.VexNum; ++v){for (int w = 0; w < G.VexNum; ++w){if ((G.arc[v][w] != 0) && visited[w] == 0){cout << G.vex[w];visited[w] = 1;}}}//算法时间复杂度O(n^2)
}

我感觉这个写的就是逐个访问输出

不过也无所谓了,这玩意不是很重要,而且总归是能写的