#include<iostream>
#include<string>
#include <conio.h>
using namespace std;
#define OtherInfo double
#define VertexType string
#define MVNum 100
int visited[MVNum];
//无向图邻接表存储结构
typedef struct ArcNode//边结点
{
int adjvex;//该边所指向的顶点的位置
struct ArcNode* nextarc;//指向下一条边的指针
OtherInfo* info;//和边相关的信息
}ArcNode;//边的邻接点信息4
typedef struct VNode
{
VertexType data;//顶点信息
ArcNode* firstarc;//指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];//AdjList表示邻接表类型
typedef struct
{
AdjList vertices;//邻接表
int vexnum,arcnum;//图的当前顶点数和边数
}ALGraph;
int Locate_vertices(ALGraph G,VertexType v)
{
for(int i=0;i!=G.vexnum;i++){
if(G.vertices[i].data==v)
return i;
}
return -1;
}
bool CreateUDG(ALGraph& G)//创建无向网的邻接表
{
int i,j;
cout<<"输入无向网的顶点数和边数(如4 3):";
cin>>G.vexnum>>G.arcnum;
// G.visited=new int[G.vexnum];
for(i=0;i!=G.vexnum;i++){
cout<<"输入顶点信息(类型为string):";
cin>>G.vertices[i].data;
G.vertices[i].firstarc=NULL;
visited[i]=0;//0代表未被遍历过
}
VertexType v1,v2;
OtherInfo w;
ArcNode* p1,* p2;
for(int k=0;k!=G.arcnum;k++){
cout<<"输入两个顶点信息和权值(如v1 v2 1):";
cin>>v1>>v2>>w;
i=Locate_vertices(G,v1);
j=Locate_vertices(G,v2);
p1=new ArcNode;
if(!p1)
return false;
p1->adjvex=j;
p1->info=new OtherInfo;
*p1->info=w;
p1->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p1;
p2=new ArcNode;
if(!p2)
return false;
p2->adjvex=i;
p2->info=new OtherInfo;
*p2->info=w;
p2->nextarc=G.vertices[j].firstarc;G.vertices[j].firstarc=p2;
}
return true;
}
void Output_UDN(ALGraph G)//输出无向图的邻接表
{
ArcNode* p;
for(int i=0;i!=G.vexnum;i++){
cout<<"顶点:"<<G.vertices[i].data;
p=G.vertices[i].firstarc;
while(p){
cout<<"->邻接点:"<<p->adjvex;
if(p->info)
cout<<"权值:"<<*p->info;
p=p->nextarc;
}
cout<<endl;
}
}
void DFS(ALGraph G,int i)//深度优先遍历无向网的邻接表
{
cout<<" "<<G.vertices[i].data;
visited[i]=1;//遍历过将visited改为1
ArcNode* p=G.vertices[i].firstarc;
while(p){
if(!visited[p->adjvex])//若没被遍历过,则对其进行DFS遍历
DFS(G,p->adjvex);
p=p->nextarc;
}
}
//构建队列为图的广度优先遍历
#define QElemType int//队列存储边的位置下标
typedef struct QNode
{
QElemType data;
struct QNode* next;
}QNode,* Qlink;
typedef struct
{
Qlink head,tail;
int len;
}LinkQueue;
bool Init_Queue(LinkQueue& Q)//初始化队列
{
Q.head=new QNode;
if(!Q.head)
return false;
Q.head->next=NULL;
Q.tail=Q.head;
Q.len=0;
return true;
}
bool IsEmpty(LinkQueue Q)
{
if(Q.len==0)
return true;
return false;
}
bool EnQueue(LinkQueue& Q,QElemType e)//入队
{
Qlink p=new QNode;
p=new QNode;
if(!p)
return false;
p->data=e;
p->next=Q.tail->next;
Q.tail->next=p;
Q.tail=p;
Q.len++;
return true;
}
bool DeQueue(LinkQueue& Q,QElemType& e)//出队
{
if(Q.len==0)
return false;
Qlink p=Q.head->next;
e=p->data;
Q.head->next=p->next;
if(p==Q.tail)
Q.tail=Q.head;
delete p;
Q.len--;
return true;
}
void BFS(ALGraph G,int i)//邻接表的广度优先搜索
{
int e;
LinkQueue Q;
Init_Queue(Q);
EnQueue(Q,i);
ArcNode* p;
while(!IsEmpty(Q)){
DeQueue(Q,e);
if(!visited[e]){//输出的同时,将其visited置为1
cout<<" "<<G.vertices[e].data;
visited[e]=1;
}
p=G.vertices[e].firstarc;
while(p){//将邻接表一行的adjvex都入队
if(!visited[p->adjvex])//若没有遍历过,入队;否则不进行操作
EnQueue(Q,p->adjvex);
p=p->nextarc;
}
}
}
void degree(ALGraph G)
{
ArcNode *p;
int n,i;
cout <<"顶点度为"<<endl;
for (i=0;i<G.vexnum;i++){
n=0;
p=G.vertices[i].firstarc;
while (p){
n++;
p=p->nextarc;
}
cout<<G.vertices[i].data<<"(顶点):(度)"<<n<<endl;
}
}
int main(){
int flag=1,ch,v,i;
ALGraph G;
while (flag)
{
cout << "------------------------" << endl;
cout << "1.生成邻接表无向图 " << endl;
cout << "2.输出节点度" << endl;
cout << "3.深度遍历" << endl;
cout << "4.广度遍历" << endl;
cout << "5.退出程序 " << endl;
cout << "------------------------" << endl;
cout <<"请输入:";
cin >> ch;
switch(ch){
case 1:
CreateUDG(G);
cout<<endl;
break;
case 2:
degree(G);
cout<<endl;
break;
case 3:
DFS(G,0);
for(i=0;i!=G.vexnum;i++){//重置visited,DFS已经通过指针改变了visited
visited[i]=0;
}
cout<<endl;
break;
case 4:
BFS(G,0);
cout<<endl;
break;
default:
flag=0;
cout << "按任意键退出程序!";
getch();
}
}
return 0;
}
无向图邻接表代码数据结构严蔚敏第二版
最新推荐文章于 2023-12-09 13:11:31 发布