数据结构--图的遍历(DFS和BFS)

博前感想:

图的遍历创建的思想比较容易懂,深度遍历和广度遍历需要自己动动脑筋。深度遍历是基于栈的思想--先进后出,广度遍历是基于队列的思想--先进先出。

代码块:

#include<string>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
//#include"x64/Debug/图的遍历.tlog/"         不行
using namespace std;

bool DFSvisit[26];                   //两个存放有没有访问过的布尔型数组
bool BFSvisit[26];

typedef struct arcNode                        //边结构体
{
	struct vNode;
	int xiabiao;                    //下标
	int weight;                    //每条弧的权重
	arcNode *next;                   //连接下一个结构体的指针
	vNode *visit;                      //访问顶点的指针
}arcNode;

typedef struct vNode                    //顶点结构体
{
	arcNode *first;
	string data;
	int linenum;
	//vNode hwq[13];
}adjlist;

typedef struct graph                       //图
{
	adjlist hwq[13];
	int vexnum, arcnum;             //总的顶点数和边数
}graphadjlist;


void create(graphadjlist &h, adjlist &w)             //创建图,加&的都是变量通用的
{
	arcNode *temp;                                   //边结构体的指针
	arcNode *q;                                       //也是同上
	cout<<"请输入顶点数:"<<endl;
	cin>>h.vexnum ; h.arcnum = 0;                     //初始化图的顶点数和边的数目
	int x = 0;                                   //用于控制边的条数
	//q=new arcNode;
	//cout<<"请输入第"<<1<<"个顶点的第"<<1<<"条边的权值和下标:"<<endl;
	//cin>>q->weight>>q->xiabiao;
	//x++;
	//temp=q;                                  //把第一个arcnode的指针赋值给temp

	//cout << "请输入每个顶点的数据和每个顶点的弧的数量:" << endl;
	for (int i = 0; i < h.vexnum; i++)                         //循环创建每一个顶点
	{
		cout << "请输入第" << i + 1 << "个顶点的数据和顶点的弧的数量:" << endl;
		cin >> h.hwq[i].data >> h.hwq[i].linenum;
		q = new arcNode;
		cout << "请输入第 " << i + 1 << " 个顶点的第 1 条边的权值和下标:" << endl;
		cin >> q->weight >> q->xiabiao;
		q->visit = NULL;                       //先把访问指针置为空
		q->next = NULL;                         //把next指针也先置为空
		temp = q;                                       //第一个边结构体保存下来
		h.hwq[i].first = temp;
		//cout << h.hwq[i].first->weight << endl;           //这里测试没有错
		for (int j = 0; j < h.hwq[i].linenum - 1; j++)           //循环创建每一条边
		{
			
			q->next = new arcNode;
			q = q->next;
			cout << "请输入第" << i + 1 << "个顶点的第" << j + 2 << "条边的权值和下标:" << endl;
			cin >> q->weight >> q->xiabiao;
			
			x++;                                                     //边结构体互相连接,边数 x 要加一
		}
		q->next = NULL;                                               //最后一个arcNode的next指针设为空指针
		// = temp;                                     //把顶点的first指针指向第一个arcNode结构体
		x++;                                                         //指向第一条边,边数 x 要加一
		//cout << h.hwq[i].first->weight << endl;                       //这里测试就有错
		
	}
	
	h.arcnum = x/2;                                                       //最后把x作为图的总边数


	cout << "图的总顶点数为:" << h.vexnum << endl;
	cout << "图的总边数为:" << h.arcnum << endl;                             //输出测试


	/*
	int number = 0;
	for (int k = 0; k < h.vexnum; k++)
	{
		q = h.hwq[k].first;
		q->visit = h.hwq[q->xiabiao];
		for (int l = 0; l < h.hwq[k].linenum - 1; l++)
		{
			q = q->next;
			q->visit = h.hwq[q->xiabiao];
		}
	}
	*/


}

//图创建完成

//打印函数
void display(graphadjlist h, adjlist w)
{
	arcNode *q;
	for (int i = 0; i < h.vexnum; i++)
	{
		 q = h.hwq[i].first;
		//cout << q->weight << endl;
		cout << "第"<<i+1<<"个顶点:"<<h.hwq[i].data<<"-->"<<"[权值:"<<q->weight<<"下标:"<<q->xiabiao<<"]";
		q = q->next;
		for (int j = 0; j < h.hwq[i].linenum-1; j++)
		{
			cout << "-->" << "[权值:" << q->weight << "下标:" << q->xiabiao<<"]";
			q = q->next;
		}
		cout << endl;
	}
}

/*深度遍历*/
void DFS(graphadjlist h,adjlist w,int k)
{
	arcNode *p;
	if(DFSvisit[k]==false)             //为假时才输出
	{
		cout << h.hwq[k].data << " ";
	}
	DFSvisit[k] = true;
	//cout << h.hwq[k].data << " ";
	p = h.hwq[k].first;              //指向第一个arcNode结构体
	while (p)
	{
		if (DFSvisit[p->xiabiao] == false)   //如果没访问过的
		{
			DFS(h, w, p->xiabiao);
		}
		p = p->next;         //如果DFS[p->xiabiao]==true,就指向下一个arcNode
	}
}

void DFSshow(graphadjlist h, adjlist w)
{
	int i = 0; int k = 0;
	for (i; i < h.vexnum; i++)       //初始时默认全部为未访问过的
	{
		DFSvisit[i] = false;
	}
	for (k; k < h.vexnum; k++)      //这个循环可以让不连通的多个分图都遍历出来
	{
		if (!DFSvisit[k])
		{
			DFS(h, w,k);
		}
	}
}


/*广度遍历*/
void BFS(graphadjlist h)
{
	arcNode *p;
	queue<int> q;
	for (int i = 0; i < h.vexnum; i++)      //先把布尔型数组全部置为false
	{
		BFSvisit[i] = false;
	}
	for (int j = 0; j < h.vexnum; j++)               //一个点一个点的访问,虽然可能前几个点就访问完了
	{
		if (BFSvisit[j] == false)
		{
			BFSvisit[j] = true;
			cout << h.hwq[j].data << " ";
			q.push(j);                               //把输出过的下标推入队列中
			while (!q.empty())     //非空的时候
			{
				int temp = q.front();            //定义一个临时变量把队列里面的最前面的下标取出来
				q.pop();                             //用完就提取出来
				p = h.hwq[temp].first;                   //把p指针指向第一个arcNode
				while (p)                                 //这个循环用于把一个顶点结构体的相关联的顶点结构体的数据都输出出来
				{
					if (BFSvisit[p->xiabiao]==false)
					{
						BFSvisit[p->xiabiao] = true;
						cout << h.hwq[p->xiabiao].data << " ";                 						q.push(p->xiabiao);

					}
					p = p->next;
				}
			}
			
		}
	}
}

int main()
{
	graphadjlist hwq;
	adjlist wwq;
	create(hwq,wwq);
	display(hwq, wwq);

	cout << "深度遍历为:" << endl;
	DFSshow(hwq, wwq);
	DFS(hwq, wwq,0);

	cout << endl;
	cout << "广度遍历为:" << endl;
	BFS(hwq);
	cout << endl;
	system("pause");
	return 0;
}

代码大家可以多理解,还是比较好理解的,还是希望能够得到大家的意见和建议,谢谢大家。

猜你喜欢

转载自blog.csdn.net/HWQlet/article/details/86655091