实验八图的遍历操作
一、 实验目的
1.掌握图的基本存储方法;
2.熟练掌握图的两种搜索路径的遍历方法。
二、 实验内容。
1.假设图中存在以下结点:a b c d e f g, 以邻接矩阵存储,请设计程序深度优先遍历该图
2.假设图中存在以下结点:a b c d e f g, 以邻接表存储,请设计程序广度优先遍历该图
a |
c |
d |
b |
e |
f |
g |
//图的遍历是指按某条搜索路径访问图中每个结点,使得每个结点均被访问一次,而且仅被访问一次。图的遍历有深度遍历算法和广度遍历算法,程序如下:
#include
#define INFINITY 32767
#define MAX_VEX 20 //最大顶点个数
#define QUEUE_SIZE (MAX_VEX+1) //队列长度
using namespace std;
bool *visited; //访问标志数组
//图的邻接矩阵存储结构
typedef struct{
char *vexs; //顶点向量
int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}Graph;
//队列类
class Queue{
public:
void InitQueue(){
base=(int*)malloc(QUEUE_SIZE*sizeof(int));
front=rear=0;
}
void EnQueue(int e){
base[rear]=e;
rear=(rear+1)%QUEUE_SIZE;
}
void DeQueue(int &e){
e=base[front];
front=(front+1)%QUEUE_SIZE;
}
public:
int *base;
int front;
int rear;
};
//图G中查找元素c的位置
int Locate(Graph G,char c){
for(int i=0;i if(G.vexs[i]==c) return i; return -1; } //创建无向网 void CreateUDN(Graph &G){ int i,j,s1,s2; int w=1; char a,b,temp; printf("输入顶点数和弧数:"); scanf("%d%d",&G.vexnum,&G.arcnum); temp=getchar(); //接收回车 G.vexs=(char*)malloc(G.vexnum*sizeof(char)); //分配顶点数目 printf("输入%d个顶点.\n",G.vexnum); for(i=0;i printf("输入顶点%d:",i); scanf("%c",&G.vexs[i]); temp=getchar(); //接收回车 } for(i=0;i for(j=0;j G.arcs[i][j]=INFINITY; printf("输入%d条弧.\n",G.arcnum); for(i=0;i printf("输入弧%d:",i); scanf("%c %c",&a,&b); //输入一条边依附的顶点和权值 temp=getchar(); //接收回车 s1=Locate(G,a); s2=Locate(G,b); G.arcs[s1][s2]=G.arcs[s2][s1]=1; } } //图G中顶点k的第一个邻接顶点 int FirstVex(Graph G,int k){ if(k>=0 && k for(int i=0;i if(G.arcs[k][i]!=INFINITY) return i; } return -1; } //图G中顶点i的第j个邻接顶点的下一个邻接顶点 int NextVex(Graph G,int i,int j){ if(i>=0 && i for(int k=j+1;k if(G.arcs[i][k]!=INFINITY) return k; } return -1; } //深度优先遍历 void DFS(Graph G,int k){ int i; if(k==-1){ //第一次执行DFS时,k为-1 for(i=0;i if(!visited[i]) DFS(G,i); //对尚未访问的顶点调用DFS } else{ visited[k]=true; printf("%c ",G.vexs[k]); //访问第k个顶点 for(i=FirstVex(G,k);i>=0;i=NextVex(G,k,i)) if(!visited[i]) DFS(G,i); //对k的尚未访问的邻接顶点i递归调用DFS } } } //主函数 void main(){ int i; Graph G; CreateUDN(G); visited=(bool*)malloc(G.vexnum*sizeof(bool)); printf("\n深度优先遍历:"); for(i=0;i visited[i]=false; DFS(G,-1); printf("\n程序结束.\n"); } #include #include #include using namespacestd; //下面是循环队列模版 template classMy_queue; template class Node { private: T data; Node public: Node() { next=0; } Node(T d) { data=d; next=0; } friend My_queue }; template classMy_queue { private: Node public: My_queue() { tail=new Node tail->next=tail; } ~My_queue() { clean(); delete tail; } bool empty() { return (tail->next==tail); } void push(T d) { Node p->next=tail->next; tail->next=p; tail=p; } T front() { if(empty()) { cout<<"queue isempty!"< exit(0); } Node T data=p->next->data; return data; } T back() { if(empty()) { cout<<"queue isempty!"< exit(0); } T data=tail->data; return data; } void pop() { Node Node p->next=q->next; if(q==tail) tail=p; delete q; } void clean() { Node Node while(q!=p) { p->next=q->next; delete q; p->next=q; } } }; #defineMAX_VERTEX_NUM 20 boolvisited[20];//用于遍历时辅组使用 int Vex_Num;//统计输出顶点数目 //表结点 structArcNode { int adjvex; //弧所指向顶点的位置 ArcNode *nextarc;// 指向下一条弧 }; //头结点 typedef structVNode { string data;//顶点名 ArcNode *firstarc;//指向第一条关联顶点的弧 }AdjList[MAX_VERTEX_NUM]; structALGraph { AdjList vertices;//头结点数组 int vexnum;//顶点数 int arcnum;//边数 }; intLocate_Vex(ALGraph G,string x) //定位顶点位置 { for(intv=0;G.vertices[v].data!=x;v++); return v; } voidCreateDG_ALG(ALGraph &G) { //采用邻接表存储表示,构造有向图G string v1,v2; int i,j,k; cout<<"输入顶点数和边数:"; cin>>G.vexnum>>G.arcnum; //构造头结点数组 cout<<"输入顶点民称:"; for(i=0;i { cin>>G.vertices[i].data; G.vertices[i].firstarc=NULL; } //输入各弧并构造邻接表 for(k=0;k { cout<<"按尾->头的顺序输入边所对应的两个顶点:"; cin>>v1>>v2; i=Locate_Vex(G,v1); j=Locate_Vex(G,v2); while(i<0|| i>G.vexnum-1 ||j<0 || j>G.vexnum-1) { cout<<"结点位置输入错误,重新输入: "; cin>>v1>>v2; i=Locate_Vex(G,v1); j=Locate_Vex(G,v2); } ArcNode *p=new ArcNode; p->adjvex=j; p->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=p; } } //深度优先遍历 void DFS(ALGraphG,int v) { visited[v]=true; cout< Vex_Num+=1; if(Vex_Num==G.vexnum) return; ArcNode *p; int w; for(p=G.vertices[v].firstarc;p;p=p->nextarc) { w=p->adjvex; if(!visited[w]) DFS(G,w); } } voidDFS_Traverse(ALGraph G) { Vex_Num=0; int i,k; for(i=0;i visited[i]=false; for(k=0;k if(!visited[k]) DFS(G,k); } //广度优先遍历 voidBFS_Traverse(ALGraph G) { Vex_Num=0; int i,k,w; My_queue ArcNode *p; for(i=0;i visited[i]=false; for(i=0;i { if(!visited[i]) { visited[i]=true; cout< Vex_Num+=1; if(G.vertices[i].firstarc) q.push(i); while(!q.empty()) { k=q.front(); q.pop(); for(p=G.vertices[k].firstarc;p;p=p->nextarc) { w=p->adjvex; if(!visited[w]) { visited[w]=true; cout< Vex_Num+=1; if(Vex_Num==G.vexnum) break; if(G.vertices[w].firstarc) q.push(w); } } } } } } int main() { ALGraph G; CreateDG_ALG(G); cout<<"深度优先遍历图为:"; DFS_Traverse(G); cout< cout<<"广度优先遍历图为:"; BFS_Traverse(G); cout< return 0; }