数据结构_图_求无向图的关节点

"head.h"


#include<iostream>
using namespace std;

#define MAX_VEX_NUM 20

class ChildNode//存储以某顶点为边的一个顶点的另一个顶点
{
public:
	ChildNode();
	int child;
	ChildNode *next;
};

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

class VexNode//顶点信息
{
public:
	VexNode();
	char name;
	int visitsq;//访问顺序
	int low;//low值
	ChildNode *firstchild;
};

VexNode::VexNode()
{
	visitsq=low=0;
	firstchild=NULL;
}

class VexBox//顶点集合
{
public:
	VexBox();
	int vexnum;
	VexNode vexbox[MAX_VEX_NUM];
};

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

class ArtPoint//Articulation Point//关节点类
{
public:
	void GetArtPoint();//接口函数
private:
	void GetVexNode();//得到顶点信息
	void GetEdge();//得到边的信息
	void FindArticul();//找关节点
	void DFSArticul(int);//深度优先遍历图
	VexBox v;
	int count;
};

void ArtPoint::GetArtPoint()//接口函数
{
	GetVexNode();//得到顶点信息
	GetEdge();//得到边的信息
	FindArticul();//找关节点
}

void ArtPoint::GetVexNode()//得到顶点信息
{
	cout<<"Please Input The Name Of The Vertex :"<<endl<<endl;
	char name;
	while(cin>>name)
	{
		v.vexbox[v.vexnum++].name=name;
	}
	cin.clear();
}

void ArtPoint::GetEdge()//得到边的信息
{
	cout<<"Please Input The Two Nodes Which Made A Edge :"<<endl<<endl;
	int t[2];
	ChildNode *p,*newnode;
	while(cin>>t[0]>>t[1])
	{
		for(int i=0;i<2;i++)
		{
			newnode=new ChildNode;
			newnode->child=t[1-i];
			if((p=v.vexbox[t[i]].firstchild)==NULL)
			{
				v.vexbox[t[i]].firstchild=newnode;
			}
			else
			{
				while(p->next!=NULL)
				{
					p=p->next;
				}
				p->next=newnode;
			}
		}
	}
	cin.clear();
}

void ArtPoint::FindArticul()//找关节点
{
	count=1;//初始化count记录访问次序
	v.vexbox[0].visitsq=1;
	DFSArticul(0);//从第一个节点开始访问
	if(count<v.vexnum)//如果生成树的根有两颗或两颗以上子树
	{
		cout<<v.vexbox[0].name<<endl;//该节点为关节点输出之
	}
	for(int i=1;i<v.vexnum;i++)//访问剩余未被访问的节点
	{
		if(v.vexbox[i].visitsq==0)
		{
			DFSArticul(i);
		}
	}
}

void ArtPoint::DFSArticul(int n)//深度优先遍历图
{
	//该节点的low值被定义为MIN{当前节点的访问次序,孩子节点的low值,祖先节点的访问次序}
	int min=v.vexbox[n].visitsq=++count;//初始化min
	ChildNode *p=v.vexbox[n].firstchild;
	while(p!=NULL)//访问与该顶点有边相连的所有顶点
	{
		if(v.vexbox[p->child].visitsq==0)//访问的是孩子节点
		{
			DFSArticul(p->child);//以该顶点开始深度优先遍历图
			if(v.vexbox[p->child].low<min)//如果孩子节点的low值有小于min的
				min=v.vexbox[p->child].low;//更新当前节点的low值
			if(v.vexbox[p->child].low>=v.vexbox[n].visitsq)//如果孩子节点的low值大于等于当前节点的访问次序
				//说明该树的根和子树中的其他节点均没有指向当前节点的祖先的节点
				cout<<v.vexbox[n].name<<endl;//该节点为关节点
		}else if(v.vexbox[p->child].visitsq<min)//访问的是祖先节点//如有必要更新min
			min=v.vexbox[p->child].visitsq;
		p=p->next;
	}//while
	v.vexbox[n].low=min;//将获得的最小的min作为当前节点的low值
}



"main.cpp"


#include"head.h"

int main()
{
	ArtPoint p;
	p.GetArtPoint();
	system("pause");
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值