数据结构_图_邻接表做存储结构实现求无向图的连通分量_C++实现

数据结构_图_邻接表做存储结构实现求无向图的连通分量_C++实现

调了一个晚上终于把这段程序给调通了,原来对孩子兄弟链表的理解有点偏差,还有就是对递归有了跟深刻的理解,当然最大的收获就是发现程序中错误的能力进一步提高,借助于Visual Stdio这个强大的编程环境,可以让我迅速地积累编程经验,快速的发现程序中隐含的漏洞,而且他强大的自定义功能也让编程变得得心应手。推荐使用。。。

head.h


#include<iostream>
#define MAX_VEX_NUM 20
using namespace std;

class NODE //记录孩子结点的序号等信息
{
public:
	NODE();
	int child;
	NODE *next;
};

NODE::NODE()
{
	child = 0;
	next = NULL;
}

class VexNode //记录顶点信息
{
public:
	VexNode();
	bool visited;
	char vexname;
	NODE *firstchild;
};

VexNode::VexNode()
{
	visited = false;
	firstchild = NULL;
}

class VexBox //储存图的邻接表
{
public:
	VexBox();
	VexNode vexbox[MAX_VEX_NUM];
	int vexnum;
};

VexBox::VexBox()
{
	vexnum = 0;
}

class CSTreeNode //生成树节点
{
public:
	CSTreeNode();
	char name;
	CSTreeNode *lchild, *rsibling;
};

CSTreeNode::CSTreeNode()
{
	lchild = rsibling = NULL;
}

class Graph
{
public:
	Graph();
	void ShowGraph(); //接口函数
private:
	void GetVexList(); //得到顶点信息
	void GetChild(); //得到各个顶点的孩子信息
	void DFSForest();
	void DFSTree(int, CSTreeNode*);
	void Print(); //输出图的顶点孩子信息
	void PrintTree();
	void InOrderPrintTree(CSTreeNode*); //中序输出生成树
	VexBox l; //定义一个邻接表
	CSTreeNode *root; //生成树根
};

Graph::Graph()
{
	root = NULL;
}

void Graph::ShowGraph() //接口函数
{
	cout << "ShowGraph Called !" << endl << endl;
	GetVexList(); //得到顶点信息
	GetChild(); //得到各个顶点的孩子信息
	Print(); //输出邻接表信息
	DFSForest(); //深度优先遍历该图并建立连通分量的生成森林
	PrintTree(); //输出各连通分量
}

void Graph::GetVexList() //得到顶点信息
{
	cout << "GetVexList Called !" << endl << endl;
	cout << "Please Enter The Vertexes :" << endl << endl;
	char name;
	while (cin >> name)
	{
		l.vexbox[l.vexnum++].vexname = name;
	}
	cin.clear();
}

void Graph::GetChild() //得到各个顶点的孩子信息
{
	cout << "GetChild Called !" << endl << endl;
	int num;
	NODE *p, *newnode;
	for (int i = 0; i < l.vexnum; i++)
	{
		cout << "Input The Children Of VerTex " << l.vexbox[i].vexname << " : "
				<< endl << endl;
		while (cin >> num)
		{
			newnode = new NODE;
			newnode->child = num;
			if ((p = l.vexbox[i].firstchild) == NULL)
			{
				l.vexbox[i].firstchild = newnode;
			}
			else
			{
				while (p->next != NULL)
				{
					p = p->next;
				}
				p->next = newnode;
			}
		}
		cin.clear();
	}
}

void Graph::Print() //输出邻接表信息
{
	cout << "Print Called !" << endl << endl;
	NODE *p;
	for (int i = 0; i < l.vexnum; i++)
	{
		p = l.vexbox[i].firstchild;
		cout << l.vexbox[i].vexname << " : " << endl;
		while (p != NULL)
		{
			cout << "\t" << l.vexbox[p->child].vexname << endl;
			p = p->next;
		}
	}
}

void Graph::DFSForest() //深度优先遍历该图并建立连通分量的生成森林
{
	cout << "DFSForest Called !" << endl << endl;
	CSTreeNode *p, *newnode;
	for (int i = 0; i < l.vexnum; i++) //对列表内的所有节点进行遍历
	{
		if (l.vexbox[i].visited == false) //如果未被访问
		{
			newnode = new CSTreeNode; //新开辟一个节点
			newnode->name = l.vexbox[i].vexname; //当前节点名字赋给新的节点
			if (root == NULL) //如果root未指向任何节点
			{
				p = root = newnode;
			}
			else
			{
				p->rsibling = newnode; //否则就把新开辟的节点挂在右兄弟上
				p = p->rsibling; //p指向新开辟的节点
			}
			DFSTree(i, p); //以p为根节点建立新树
		}
	}
}

void Graph::DFSTree(int i, CSTreeNode *t) //左孩子右兄弟,左孩子右兄弟!!!在这纠结了半天
{
	bool first = true;
	l.vexbox[i].visited = true; //标记为已访问
	NODE *q = l.vexbox[i].firstchild;
	CSTreeNode *newnode, *p;
	while (q != NULL)
	{
		if (l.vexbox[q->child].visited == false) //如果未被访问
		{
			l.vexbox[q->child].visited = true;
			newnode = new CSTreeNode;
			newnode->name = l.vexbox[q->child].vexname;
			if (first) //孩子
			{
				t->lchild = newnode;
				p = newnode;
				first = false;
			}
			else //兄弟
			{
				p->rsibling = newnode;
				p = p->rsibling;
			}
			DFSTree(q->child, newnode);
		}
		q = q->next;
	}
}

void Graph::PrintTree() //调用InOrderPrintTree()输出生成森林的相关信息
{
	cout << "PrintTree Called !" << endl << endl;
	CSTreeNode *p = root;
	while (p != NULL)
	{
		cout << p->name;
		InOrderPrintTree(p->lchild);
		cout << endl << endl;
		p = p->rsibling;
	}
}

void Graph::InOrderPrintTree(CSTreeNode *t) //递归遍历每一棵树
{
	if (t == NULL)
		return;
	cout << t->name;
	InOrderPrintTree(t->lchild);
	InOrderPrintTree(t->rsibling);
}

main.cpp

#include"head.h"
 
int main()
{
    Graph g;
    g.ShowGraph();
	system("pause");
}

发表回复