无向图的深度优先生成树

用邻接表存储的无向图的深度优先生成树,树结点用孩子兄弟结构保存。下面是代码

#include<iostream> #include<string> using namespace std; #define MAX_VERTEX_NUM 20 bool visited[20];//用于遍历时辅助使用 bool searched[20];//用于建树时辅助使用 //循环队列模版 template<class T> class My_queue; template<class T> class Node { private: T data; Node<T> *next; public: Node() { next=0; } Node(T d) { data=d; next=0; } friend My_queue<T>; }; template<class T> class My_queue { private: Node<T> *tail; public: My_queue() { tail=new Node<T>(); tail->next=tail; } bool empty() { return (tail->next==tail); } void push(T d) { Node<T> *p=new Node<T>(d); p->next=tail->next; tail->next=p; tail=p; } T front() { if(empty()) { cout<<"queue is empty!"<<endl; exit(0); } Node<T> *p=tail->next; T data=p->next->data; return data; } void pop() { Node<T> *p=tail->next; Node<T> *q=p->next; p->next=q->next; if(q==tail) tail=p; delete q; } }; class ALGraph; class CS_Tree; //树结点 class CSnode { string data; CSnode *firstchild; CSnode *nextsibling; friend class CS_Tree; friend class ALGraph; }; //树类定义 class CS_Tree { public: void PreRoot_Traverse(CSnode *T) //先根遍历 { if(T) { cout<<T->data<<" "; PreRoot_Traverse(T->firstchild); PreRoot_Traverse(T->nextsibling); } } void PostRoot_Traverse(CSnode *T) //后根遍历 { if(T) { PostRoot_Traverse(T->firstchild); cout<<T->data<<" "; PostRoot_Traverse(T->nextsibling); } } void LevelOrder_Traverse(CSnode *T) //层次遍历 { My_queue<CSnode *> q; CSnode *t; q.push(T); do { t=q.front(); do { cout<<t->data<<" "; if(t->firstchild) q.push(t->firstchild); t=t->nextsibling; }while(t); q.pop(); }while(!q.empty()); } }; class VNode; //表结点 class ArcNode { public: int adjvex; ArcNode *nextarc; friend class VNode; }; class ALGraph; //头结点 class VNode { string data; ArcNode *firstarc; friend class ALGraph; }; class ALGraph { private: VNode vertices[MAX_VERTEX_NUM]; int vexnum; int arcnum; static int VEX_NUM; //统计输出顶点数目,节省时间 public: void CreateUDG_ALG() { //采用邻接表构造无向图G string v1,v2; int i,j,k; cout<<"输入顶点数和边数:"; cin>>vexnum>>arcnum; cout<<"输入顶点民称:"; for(i=0;i<vexnum;i++) { cin>>vertices[i].data; vertices[i].firstarc=NULL; } //输入各弧并构造邻接表 for(k=0;k<arcnum;k++) { cout<<"输入边所对应的两个顶点:"; cin>>v1>>v2; i=Locate_Vex(v1); j=Locate_Vex(v2); while(i<0|| i>vexnum-1 || j<0 || j>vexnum-1) { cout<<"结点位置输入错误,重新输入: "; cin>>v1>>v2; i=Locate_Vex(v1); j=Locate_Vex(v2); } ArcNode *p=new ArcNode; p->adjvex=j; p->nextarc=vertices[i].firstarc; vertices[i].firstarc=p; ArcNode *q=new ArcNode; q->adjvex=i; q->nextarc=vertices[j].firstarc; vertices[j].firstarc=q; } } int Locate_Vex(string v) //返回顶点在数组中的位置 { for(int k=0;vertices[k].data!=v;k++); return k; } void DFS_Traverse() //深度优先遍历 { VEX_NUM=0; int i,k; for(i=0;i<vexnum;i++) visited[i]=false; for(k=0;k<vexnum;k++) if(!visited[k]) DFS(k); } void DFS(int v) { visited[v]=true; cout<<vertices[v].data<<" "; VEX_NUM++; if(VEX_NUM==vexnum) return; ArcNode *p; int w; for(p=vertices[v].firstarc;p;p=p->nextarc) { w=p->adjvex; if(!visited[w]) DFS(w); } } //在建立深度优先生成树之前,先将v号位置的顶点给根节点T CSnode *Pre_Tree(int v,CSnode *T) { T=new CSnode; T->data=vertices[v].data; return T; } void DFS_Tree(int v,CSnode *&T) { /*---------------------------------------------/ //深度优先生成树,从v位置开始建立以T为根节点的树 // //如果在这里面才进行第一个结点给根结点,那么 // //在递归过程中会出现错误,所以才在进入建树前 // //先将v号结点给根节点 // /------------------------------------------*/// T->firstchild=T->nextsibling=NULL; searched[v]=true; bool first=true;//判断是否为v的第一个未访问尚的邻接结点 int w; CSnode *t,*q; ArcNode *f; for(f=vertices[v].firstarc;f;f=f->nextarc) { w=f->adjvex; if(!searched[w]) { q=new CSnode; q->data=vertices[w].data; q->firstchild=q->nextsibling=NULL; if(first) { T->firstchild=q; first=0; } else t->nextsibling=q; t=q; DFS_Tree(w,t); } } } }; int ALGraph::VEX_NUM=0; int main() { CSnode *T; CS_Tree tree; ALGraph G; G.CreateUDG_ALG(); cout<<"深度优先遍历图为:"; G.DFS_Traverse(); cout<<endl; for(int i=0;i<20;i++) searched[i]=false; cout<<"输入要从第几号顶点开始建立深度优先生成树:"; int v; cin>>v; T=G.Pre_Tree(v,T); cout<<"____建立深度优先生成树____"<<endl; G.DFS_Tree(v,T); cout<<"____建树完成____"<<endl; cout<<"生成树的先根遍历为:"; tree.PreRoot_Traverse(T); cout<<endl; cout<<"生成树的后根遍历为:"; tree.PostRoot_Traverse(T); cout<<endl; cout<<"生成树的层次遍历为:"; tree.LevelOrder_Traverse(T); cout<<endl; return 0; }

测试结果:

输入顶点数和边数:9 15 输入顶点民称:v1 v2 v3 v4 v5 v6 v7 v8 v9 输入边所对应的两个顶点:v1 v6 输入边所对应的两个顶点:v1 v7 输入边所对应的两个顶点:v1 v2 输入边所对应的两个顶点:v2 v7 输入边所对应的两个顶点:v2 v3 输入边所对应的两个顶点:v6 v5 输入边所对应的两个顶点:v6 v9 输入边所对应的两个顶点:v7 v9 输入边所对应的两个顶点:v7 v8 输入边所对应的两个顶点:v3 v8 输入边所对应的两个顶点:v3 v4 输入边所对应的两个顶点:v9 v5 输入边所对应的两个顶点:v9 v8 输入边所对应的两个顶点:v8 v4 输入边所对应的两个顶点:v5 v4 深度优先遍历图为:v1 v2 v3 v4 v5 v9 v8 v7 v6 输入要从第几号顶点开始建立深度优先生成树:0 ____建立深度优先生成树____ ____建树完成____ 生成树的先根遍历为:v1 v2 v3 v4 v5 v9 v8 v7 v6 生成树的后根遍历为:v7 v8 v6 v9 v5 v4 v3 v2 v1 生成树的层次遍历为:v1 v2 v3 v4 v5 v9 v8 v6 v7 Press any key to continue

按照上面的输入生产的无向图和生成树分别为:

红色路线就是深度优先生成树的过程

按照生成树的层次遍历和先根遍历

树的中序遍历应该是 v7 v8 v9 v6 v5 v4 v3 v2 v1 但是输出结果那里 v9 和v6是颠倒的 这里我想不通是哪里搞错了 希望知道的朋友帮忙指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值