#include<stack>
#include<iostream>
#include<queue>
#include<string>
#include<iomanip>

using namespace std;
bool visited[100];                                          //判断是否被访问过
bool searched[100];                                          //判断是否被搜索过
bool flag = 1;
struct EBox
{
 int mark;
 int ivex;                                               //该边关联的两个顶点的位置
 int jvex;
 EBox *ilink,*jlink;                                     //分别指向关联顶点的下一条边
 
};
struct VexBox{
   
 string data;                                            //顶点名称 
 EBox *firstedge;                                         //指向第一条边关联该节点的边
 
};

/***********************************/
/*创建邻接表*/
struct Arcnode {
 int v;
 Arcnode* next;
}; //表结点

struct Vnode {
 string data;
 Arcnode* arc;
}; //头结点

/*创建树 ***********************/
struct tree {
 string data;
 tree* first = NULL;
 tree* sibling = NULL;
};

struct node {
 int v;
 tree* t;
};

/***********************************/

class AMLGraph{
 
 private:
  VexBox *adjmulist;                                   //顶点数组指针
  Vnode *Vex;
     int vexnum;                                         //点数
     int arcnum;                                         //边数  
     int maxnum;                                         //最大点数
    
   public:
       
     AMLGraph(int num);
     ~AMLGraph();
     int  Locate_Vex(string v);                          //定位顶点在顶点数组中的位置
  void CreateUDG_AML();                              //邻接多重表,储存无向图
  bool Search_Arc(string v1,string v2) ;             //搜素对应的边是否存在
  void Find_Neighbour(string v);                     //输出顶点V的邻接顶点
  bool Insert_Arc(string v1,string v2);              //插入新边,不插入平行边
  void DFS_Traverse();                               //深度优先
  void DFS(int v);
  void BFS_Traverse();                               //广度优先
  void BFS(int v);                                   // 输出邻接多重表
  tree* CreatTree(int v,tree *T);
  void TreeDFS(int v,tree *T);
  void TreeBFS(int v , tree* T, queue <node> qu);
  void DFS_NO_Recursive(int v);
  void PreOrder(tree *T);
  void print_tree(tree* T, int space);
  int getvexnum(){
   return vexnum;
  }
 
};

AMLGraph::AMLGraph(int num=20){
      adjmulist = new VexBox[num];
      Vex = new Vnode [num];
   maxnum = num;
}
AMLGraph::~AMLGraph(){
      delete [] adjmulist;
}
int AMLGraph::Locate_Vex(string v){
      for(int i=0;i<vexnum;i++){
       if(adjmulist[i].data==v)
       return i;
      }
      return -1;
}                         
void AMLGraph::CreateUDG_AML(){
      string v1,v2;
      int i,j,k;
      cout<<"输入定点数目和弧的数目: ";
   cin>>vexnum>>arcnum;
  
   while(vexnum > maxnum){
     cout<<"顶点数目太多,请重新输入顶点数和边数(提示 : 顶点数目不要超过20个): ";
    cin>>vexnum>>arcnum;
   }
  
         while(arcnum>(vexnum*(vexnum-1)/2)){
     cout<<"边数目太多,请重新输入顶点数和边数(提示 :无平行边的连通图的  边数 <= 点数 * (点数-1) /  2 ): ";
    cin>>vexnum>>arcnum;
   }
   while(arcnum < vexnum-1){
     cout<<"边数目太少,请重新输入顶点数和边数(提示 :无平行边的连通图的  边数 不少于  点数-1 : ";
    cin>>vexnum>>arcnum;
   } 
   cout<<"输入每个顶点的名称: ";
   for(int t=0;t<vexnum;t++){
    string s;
    cin>>s;
   adjmulist[t].data = s;
    adjmulist[t].firstedge = NULL;
    Vex[t].data = s;
    Vex[t].arc = NULL;
  
   }
  
   cout<<"请输入各个边 "<<endl;
   
   for(k=0;k<arcnum;k++){
    
    cout<<"输入第"<<k+1<<"条边的两个顶点: ";
   cin>> v1 >> v2;
   while(Search_Arc(v1,v2)){
    cout<<"此边已存在,本图不支持存在平行边"<<endl;
    cout<<"请重新输入第"<<k+1<<"条边的两个顶点:  ";
    cin>>v1>>v2;
   }
   
   i = Locate_Vex(v1);
   j = Locate_Vex(v2);
   
    while(i==-1||j==-1){
     cout<<"两个顶点之间有不符合要求的,请重新输入 : ";
     cin>>v1>>v2;
     i = Locate_Vex(v1);
     j = Locate_Vex(v2);
    }
    
    EBox *p = new EBox;
    p->ivex = i;
    p->jvex = j;
    p->ilink = adjmulist[i].firstedge;
    p->jlink = adjmulist[j].firstedge;
    adjmulist[i].firstedge = adjmulist[j].firstedge = p;
    
    Arcnode* q= new Arcnode;
    Arcnode* t= new Arcnode;
    q->v = j;
    q->next = Vex[i].arc;
    Vex[i].arc = q;
    
    t->v = i;
    t->next = Vex[j].arc;
    Vex[j].arc = t;
     
     
  }
  cout<<"无向图构造完成"<<endl;
}
bool AMLGraph::Search_Arc(string v1,string v2){
     int  i;
     int  j;
     EBox *p;
     i = Locate_Vex(v1);
     j = Locate_Vex(v2);
  if(i==-1||j==-1){
   cout<<"顶点错误,该边不存在"<<endl;
   return false;
  }
  
  p = adjmulist[i].firstedge;
  while(p){
   if(p->ivex == i && p->jvex ==j) return true;
   else if(p->ivex == j && p->jvex ==i) return true;
   else if(p->ivex == i) p = p->ilink;
   else if(p->jvex == i) p = p->jlink;
  }
  return false;
      
}           
void AMLGraph::Find_Neighbour(string v){
 
     int i = Locate_Vex(v);
  if(i==-1){
   cout<<"该顶点不在此图中"<<endl;
   return ;
  }
  
  EBox *p = adjmulist[i].firstedge;
  if(p){
   cout<<"顶点"<<v<<"的邻接顶点为: ";
   while(p){
    if(p->ivex == i){
     cout<<adjmulist[p->jvex].data<<"  ";
     p = p->ilink;
    }
    else{
     cout<<adjmulist[p->ivex].data<<"  ";
     p = p->jlink;
     
    }
   }
  }
  else      
      cout<<"该顶点无相邻的顶点"<<endl;
  

tree* AMLGraph::CreatTree(int v,tree *T){
     T = new tree;
     T->data = Vex[v].data;
     return T;
}

void AMLGraph::print_tree(tree* T, int space) {
 if(T) {
  for(int i = 0; i < space; i++) cout << " ";
  cout << setfill('-') << setw(70 - space) << left << T->data << endl;
  if(T->first) {
   tree* t = T->first;
   while(t) {
    print_tree(t, space + 4);
    t = t->sibling;
   }
  }
 }
}

void AMLGraph::TreeDFS(int v , tree* T){

searched[v] = 1;
     bool firstSearched = true;
     int w;
     tree *t, *q;
     Arcnode* p;
     p = Vex[v].arc;                          //p是v的下一个点
     while(p){
      w = p->v;                            // w 是 P的v(p储存的数据)
      if(!searched[w]){
       q = new tree;
       q->data =  Vex[w].data;
       if(firstSearched){
          firstSearched = false;
       T -> first = q; 
       }
          else t->sibling = q;
    t = q;
    TreeDFS(w,t);       
      }
      p = p->next;
     }           
}

void AMLGraph::TreeBFS(int v , tree* T, queue <node> qu){
 
    
     searched[v] = 1;
     bool firstSearched = true;
     int w;
     tree *t, *q;
     node root;
     Arcnode* p;
     p = Vex[v].arc;                          //p是v的下一个点
     while(p){
      w = p->v;                            // w 是 P的v(p储存的数据)
      if(!searched[w]){
       searched[w] = 1;
       q = new tree;
       q->data =  Vex[w].data;
       if(firstSearched){
          firstSearched = false;
       T -> first = q; 
       }
          else t->sibling = q;
    t = q;
    if(Vex[w].arc){
     root.v = w;
     root.t = t;
     qu.push(root);
    }       
      }
      p = p->next;
     }   
     while(!qu.empty()){
         root = qu.front();
         qu.pop();
      TreeBFS(root.v , root.t , qu);
     }
}

void PreOrder(tree *T)        // 先序遍历 
{

if(T) {
     if(flag)  {
   cout << T->data;
   flag = 0;
  } else cout << "->" << T->data;
     if(T->first) PreOrder(T->first);  
     if(T->sibling) PreOrder(T->sibling);
 }
}

bool AMLGraph::Insert_Arc(string v1,string v2){
    
  if(Search_Arc(v1,v2)){
      cout<<"该边已经存在于图中,不重复插入"<<endl;
   return false;
     }
    
     int i,j;
     i = Locate_Vex(v1);
     j = Locate_Vex(v2);
    
     if(i==-1||j==-1){      
   cout<<"两个顶点中,又不符合要求的,插入失败"<<endl;
            return false;
     }
    
     EBox *p = new EBox;
     p->ivex = i;
     p->jvex = j;
     p->ilink = adjmulist[i].firstedge;
     p->jlink = adjmulist[j].firstedge;
     adjmulist[i].firstedge=adjmulist[j].firstedge=p;
    
     arcnum ++;
     return true;
    
}            
          
void AMLGraph::DFS_Traverse(){
 
     //for(int i=0;i<vexnum;i++)   visited[i] = false; 
     for(int i=0;i<vexnum;i++){
      visited[i] = false;
     }
     for(int i=0;i<vexnum;i++){
      if(!visited[i]){
       DFS(i);
      }
      cout<<endl;
     }
}                            
void AMLGraph::DFS(int v){
 
    //for(int i=0;i<vexnum;i++)   visited[i] = false; 
    bool flag = true;
    visited[v] = true;
        if(flag)  {
   cout<<adjmulist[v].data<<"  ";
   flag = 0;
   } else cout << "-> " <<adjmulist[v].data<<"  ";
    EBox *p = adjmulist[v].firstedge;
    while(p){
           if(p->ivex == v){
                if(!visited[p->jvex])
                   DFS(p->jvex);
             p = p->ilink;
           }
        else{
             if(!visited[p->ivex])
                   DFS(p->ivex);
             p = p->jlink;
           } 
    }
}
void AMLGraph::BFS_Traverse(){
 
     for(int i=0;i<vexnum;i++)
             visited[i]=false;
        for(int i=0;i<vexnum;i++)
             if(!visited[i])
                  BFS(i);
        cout<<endl;

}                              
void AMLGraph::BFS(int v){
  
  //for(int i=0;i<vexnum;i++)   visited[i] = false; 
        visited[v]=true;
       
        if(flag)  {
   cout<<adjmulist[v].data<<"  ";
   flag = 0;
   } else cout << "-> " <<adjmulist[v].data<<"  ";
        EBox *p;
        int pos;
        queue<int> qu;
        qu.push(v);
        while(!qu.empty())
        {
            pos=qu.front();
            qu.pop();
            p=adjmulist[pos].firstedge;
            while(p)
            {
                if(p->ivex == pos)
                {
                    if(!visited[p->jvex])
                    {
                        visited[p->jvex]=true;
                        if(flag)  {
                        cout<<adjmulist[p->jvex].data<<"  ";
                        flag = 0;
                   } else cout << "-> " <<adjmulist[p->jvex].data<<"  ";
                        qu.push(p->jvex);
                    }
                    p=p->ilink;
                }
                else
                {
                    if(!visited[p->ivex])
                    {
                        visited[p->ivex]=true;
                        if(flag)  {
                        cout<<adjmulist[p->ivex].data<<"  ";
                        flag = 0;
                   } else cout << "-> " << adjmulist[p->ivex].data<<"  ";
                        qu.push(p->ivex);
                    }
                    p=p->jlink;
                }
            }       
        }
}

void AMLGraph::DFS_NO_Recursive(int v){
 
 //for(int i=0;i<vexnum;i++)   visited[i] = false;   
 EBox* p;
 stack <int> st;
 int pos;
 bool flag = 1;
 if(!visited[v]) {
  visited[v] = true;
  if(flag)  {
   cout<<adjmulist[v].data<<"  ";
   flag = 0;
   } else cout << "-> " <<adjmulist[v].data<<"  ";
  st.push(v);
  while(!st.empty()) {
   pos = st.top();
   p=adjmulist[pos].firstedge;
   while(p) {
    if(p->ivex == pos) {
     if(!visited[p->jvex]) {
      visited[p->jvex] = 1;
      if(flag)  {
       cout<<adjmulist[p->jvex].data<<"  ";
       flag = 0;
      } else cout << "-> " <<adjmulist[p->jvex].data<<"  ";
      st.push(p->jvex);
      break;
     }
     p = p->ilink;
    } else {
     if(!visited[p->ivex]) {
      visited[p->ivex] = 1;
      if(flag)  {
       cout<<adjmulist[p->ivex].data<<"  ";
       flag = 0;
      } else cout << "-> " << adjmulist[p->ivex].data<<"  ";
      st.push(p->ivex);
      break;
     }
     p = p->jlink;
    }
   }
   if(!p) st.pop();
  }
 }
}

void run(){
 
  cout<<"********************************************************************"<<endl;
  cout<<"                          无向图的遍历                              "<<endl;
  cout<<"              请根据提示进行必要的输入以确保图的输入                "<<endl;
  AMLGraph a;
  a.CreateUDG_AML();
  int run = 1;
  while(run){
    cout<<" 输入 1 ---------对图进行邻接多重表存储图的深度优先遍历(递归)     "<<endl;
    cout<<" 输入 2 ---------对图进行邻接多重表存储图的广度优先遍历             "<<endl;
    cout<<" 输入 3 ---------深度优先生成树输出                                 "<<endl;
    cout<<" 输入 4 ---------广度优先生成树输出                                 "<<endl;
    cout<<" 输入 5 ---------对图进行邻接多重表存储图的深度优先遍历(非递归)     "<<endl;
    cout<<" 输入 0 ---------结束程序                                           "<<endl;
    int c;
   cin>>c;
   while(c<0||c>5){
          cout<<"输入不符合规则选项,请确保输入无误后重新输入>>>     ";
          cin>>c;
         }
   
   switch(c){
         case 0:
     {      system("cls");
            cout<<"谢谢使用!程序结束!"<<endl;
             run = 0;
              break;
         }
         case 1:
     {
              system("cls");
              cout<<"请输入一个遍历的起点>>>>>>  输入起点名字 >>>>>>";
              string s;
              cin>>s;
             
              while(a.Locate_Vex(s)==-1){
                             cout << "该顶点不存在! 请重新输入起点的名字>>>>> ";
              cin >> s;
               }
              cout<<"对图进行邻接多重表存储图的深度优先遍历(递归)为"<<endl;
              for(int i=0;i<a.getvexnum();i++)   visited[i] = false; 
         a.DFS(a.Locate_Vex(s));
         
              break;
         }
        
         case 2:
                 {
              system("cls");
              cout<<"请输入一个遍历的起点>>>>>>  输入起点名字 >>>>>>";
              string s;
              cin>>s;
              while(a.Locate_Vex(s)==-1){
                             cout << "该顶点不存在! 请重新输入起点的名字>>>>> ";
              cin >> s;
               }
                     cout<<"对图进行邻接多重表存储图的广度优先遍历为"<<endl;
                     for(int i=0;i<a.getvexnum();i++){
                          visited[i] = 0;
                          searched[i] = 0;
                     }
              a.BFS(a.Locate_Vex(s));
             
             break;
         }
        
         case 3:
         {
              system("cls");
              cout<<"请输入一个遍历的起点>>>>>>  输入起点名字 >>>>>>";
              string s;
              cin>>s;
              while(a.Locate_Vex(s)==-1){
                             cout << "该顶点不存在! 请重新输入起点的名字>>>>> ";
              cin >> s;
               }
                        cout<<"对图进行邻接多重表存储图的深度优先遍历为"<<endl;
              a.DFS(a.Locate_Vex(s));
              cout<<endl;
      cout<<"深度优先生成树输出为"<<endl;
      tree *T;
      for(int i=0;i<a.getvexnum();i++)   visited[i] = false; 
      
      T =  a.CreatTree(a.Locate_Vex(s),T);
      a.TreeDFS(a.Locate_Vex(s),T);
      a.print_tree(T, a.Locate_Vex(s));
      cout<<endl;
      
             break;
         }            
    
         case 4:
     {
              system("cls");
              cout<<"请输入一个遍历的起点>>>>>>  输入起点名字 >>>>>>";
              string s;
              cin>>s;
              while(a.Locate_Vex(s)==-1){
                             cout << "该顶点不存在! 请重新输入起点的名字>>>>> ";
              cin >> s;
               }
                        cout<<"对图进行邻接多重表存储图的广度优先遍历为"<<endl;
                        for(int i=0;i<a.getvexnum();i++)   visited[i] = false;
              a.BFS(a.Locate_Vex(s));
              cout<<endl;
      cout<<"广度优先生成树输出为"<<endl;
      tree *T;
      for(int i=0;i<a.getvexnum();i++)   searched[i] = false; 
      T =  a.CreatTree(a.Locate_Vex(s),T);
      queue<node> qu;
      a.TreeBFS(a.Locate_Vex(s),T,qu);
      a.print_tree(T, a.Locate_Vex(s));
      cout<<endl;

break;
         }
         case 5:
     {
              system("cls");
              cout<<"请输入一个遍历的起点>>>>>>  输入起点名字 >>>>>>";
              string s;
              cin>>s;
             
              while(a.Locate_Vex(s)==-1){
                             cout << "该顶点不存在! 请重新输入起点的名字>>>>> ";
              cin >> s;
               }
              cout<<"对图进行邻接多重表存储图的深度优先遍历(非递归)为"<<endl;
              for(int i=0;i<a.getvexnum();i++)   visited[i] = false; 
            a.DFS_NO_Recursive(a.Locate_Vex(s));
            cout<<endl;
              break;
         }                  
        
   }
   
  }
 
}
int main(){
 run();
 return 0;
}

2016 12 21 的project 未注释版的更多相关文章

  1. iOS 最新App提交上架流程及部分问题的解决方案2016.12.21,感谢原博主!!!

    内容摘自http://www.cocoachina.com/bbs/3g/read.php?tid=330302,原博特别详细,下面我对部分地方进行了修改,主要是对在打包验证和上传的时候遇到的问题进行 ...

  2. 2016/12/21 dplの课练

    1.将/etc/passwd第行的最后一段全部改成/bin/bash cat 1 |sed -n '1,$p' |egrep '.*:' -o |sed 's/$/\bin\/bash/' 2.将/e ...

  3. 更新日志(建议升级到2016.12.17) && 更新程序的方法

    更新程序的方法: 1,在控制面板里点击备份当前数据库文件到磁盘,把当天获取的信息从内存写到磁盘/存储卡.2,下载最新版的源码 wget -O "infopi.zip" " ...

  4. mysql查询练习题-2016.12.16

    >>>>>>>>>> 练习时间:2016.12.16 编辑时间:2016-12-20-->22:12:08 题: 涉及:多表查询.ex ...

  5. U3D笔记11:47 2016/11/30-15:15 2016/12/19

    11:47 2016/11/30Before you can load a level you have to add it to the list of levels used in the gam ...

  6. FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM

    FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM T.. = Timeline support 支持时间轴 .S. = Slice t ...

  7. OD调试学习笔记7—去除未注册版软件的使用次数限制

    OD调试学习笔记7—去除未注册版软件的使用次数限制 本节使用的软件链接 (想自己试验下的可以下载) 一:破解的思路 仔细观察一个程序,我们会发现,无论在怎么加密,无论加密哪里,这个程序加密的目的就是需 ...

  8. OD调试6—使未注册版软件的功能得以实现

    OD调试6—使未注册版软件的功能得以实现 本节使用的软件下载链接 (想动手试验的朋友可以下载来试试) 继续开始我OD调试教程的学习笔记. 本次试验对真正的程序进行逆向.(之前的都是为破解而专门设计的小 ...

  9. BabelMap 12.0.0.1 汉化版(2019年3月11日更新)

    软件简介 BabelMap 是一个免费的字体映射表工具,可辅助使用<汉字速查>程序. 该软件可使用系统上安装的所有字体浏览 Unicode 中的十万个字符,还带有拼音及部首检字法,适合文献 ...

随机推荐

  1. awk的涂鸦

    awk太牛了,博大精深,学不透,学了不用,又忘. 所以花了一天,自己总结了基础,以后就当字典查(容易忘).有不对的地方,忘大家指出. [ganzl@cmdb ~]$ more /etc/passwd ...

  2. NDO to PNP( ndoutils to PNP4Nagios)

    How to use this script The aim of this script is to import your ndo database directly into PNP4nagio ...

  3. 采用css实现流动的边框

    问题起缘一个曾经做过的项目, 类似excel那样, 选中单元格并复制或粘贴时有个边框流动的效果, like this: 在前端要作出这种效果可能方法并不少, 不过我只想到了2种, 真边框与假边框, 真 ...

  4. FastDFS介绍

    相关术语 1)跟踪服务器tracker server 2)存储服务器 storage server 3)元数据  meta data --- 附件上传的说明 4)客户端 client---对程序员暴露 ...

  5. C#删除文件

    string file =System.Web.HttpContext.Current.Server.MapPath(fileUrl); if (System.IO.File.Exists(file) ...

  6. select 选项的子句

    select 选项 : 关键字 all :全部(默认值)distinct:去掉重复的查询结果.语法:select all * from 表名: 别名: 关键字:as 语法:select * from ...

  7. Delphi 中记录类型 给记录指针赋值。

    PPersion=^TPersion;  TPersion=packed record     Name:string;     Sex:string;     Clasee:string;  end ...

  8. Postgresql死锁处理

    今天遇到Postgresql的一个问题,部分表记录的update一直无效报错,初步判断为锁表,赶紧进行解决. 1. 查询死锁进程列表 select * from pg_stat_activity wh ...

  9. String.prototype运用

    1.去掉字符串前后空格 String.prototype.ltrim = function () { return this.replace(/^\s+/, ""); } Stri ...

  10. php常用的数组函数

    array_change_key_case -- 返回字符串键名全为小写或大写的数组 array_chunk -- 将一个数组分割成多个 array_combine --  创建一个数组,用一个数组的 ...