邻接表(有向图、无向图)的深度优先遍历DFS(递归和非递归)与广度优先搜索BFS

一次非常难受的数据结构实验

#include <iostream>
#define MAXVEX 100
using namespace std;

// 边表
typedef struct EdgeNode {
  int adjvex;
  EdgeNode *next;
} EdgeNode;

// 顶点
typedef struct VexNode {
  char data;
  EdgeNode *first;
} VexNode;

// 邻接表
typedef struct GraphAdjList {
  VexNode AdjList[MAXVEX];
  int vexnum;  // 顶点数
  int edgenum; // 边数
} GraphAdjList;

// 寻找
int Location(GraphAdjList &g, char c) {
  for (int i = 0; i < g.vexnum; i++) {
    if (c == g.AdjList[i].data) {
      return i;
    }
  }
  return -1;
}

// 创建邻接表
void Creat(GraphAdjList &g) {
  int i, j, k;
  char vi, vj;
  EdgeNode *e = NULL;
  EdgeNode *q = NULL;
  cout << "请输入顶点数和边数"
       << "\n";
  cin >> g.vexnum >> g.edgenum;
  cout << "请输入顶点信息: "
       << "\n";
  for (k = 0; k < g.vexnum; k++) {
    cin >> g.AdjList[k].data;
    g.AdjList[k].first = NULL;
  }

  // 建立边表
  for (k = 0; k < g.edgenum; k++) {
    cout << "请输入第" << k + 1 << "条顶点边(vi,vj)的下标i, j: "
         << "\n";
    cin >> vi >> vj;
    i = Location(g, vi);
    j = Location(g, vj);

    e = new EdgeNode;
    e->adjvex = j;
    e->next = g.AdjList[i].first;
    g.AdjList[i].first = e;

    // 如果是无向图
    //  q = new EdgeNode;
    //  q->adjvex = i;
    //  q->next = g.AdjList[j].first;
    //  g.AdjList[j].first = q;
  }
}

// 输出邻接表
void Print(GraphAdjList &g) {
  cout << "\n"
       << "邻接表: " << endl;
  EdgeNode *p;
  for (int i = 0; i < g.vexnum; i++) {
    cout << "顶点" << g.AdjList[i].data << ": ";
    for (p = g.AdjList[i].first; p; p = p->next) {
      cout << p->adjvex << " ";
    }
    cout << "\n";
  }
}

// 全局变量
int visit[MAXVEX];

// 递归
void DFS(GraphAdjList &g, int v) {
  int j;
  cout << g.AdjList[v].data << " ";
  visit[v] = 1;                     // 表示访问过
  EdgeNode *p = g.AdjList[v].first; // 邻接的第一条边
  while (p) {
    j = p->adjvex; // 和之前顶点相连的信息
    if (!visit[j])
      DFS(g, j);
    p = p->next; // 下一条边的遍历
  }
}

void DFS_All(GraphAdjList &g) {//排除非连通图
  for (int i = 0; i < g.vexnum; i++) {
    if (visit[i] == 0) {
      DFS(g, i);
    }
  }
}

// 非递归
void DFS2(GraphAdjList &g, int v) {
  int s[MAXVEX]; // 栈
  int top = -1;  // 栈顶元素
  int j;
  EdgeNode *p;
  cout << g.AdjList[v].data << " ";
  visit[v] = 1;             // 表示已访问
  s[++top] = v;             // 进栈
  while (top != -1) {       // 栈不为空就一直循环
    v = s[top];             // 栈顶元素
    p = g.AdjList[v].first; // 到相连的下一个顶点
    while (p) {
      j = p->adjvex; // 下一顶点的信息
      if (!visit[j]) {
        cout << g.AdjList[j].data << " ";
        visit[j] = 1;           // 已访问
        s[++top] = j;           // 进栈
        p = g.AdjList[j].first; // 到相连的下一顶点
      } else
        p = p->next; // 访问下一条边
    }
    top--; // 出栈
  }
}

void DFS2_All(GraphAdjList &g) {
  for (int i = 0; i < g.vexnum; i++) {
    if (visit[i] == 0) {
      DFS2(g, i);
    }
  }
}

// 广度优先遍历
void BFS2(GraphAdjList &g, int v){
  int front;
  int rear;
  int q[MAXVEX];//队列
  int j;
  front = rear = -1; //队列初始化
  EdgeNode *p;  //边结点
  cout << g.AdjList[v].data << " ";//输出当前结点
  visit[v] = 1;
  q[++rear] = v;
  //如果队列不为空
  while(front != rear){//不为空
    v = q[++front];//出队
    p = g.AdjList[v].first; // 边表工作指针初始化
    while(p){
      j = p->adjvex;//下一顶点
      if(!visit[j]){
        cout << g.AdjList[j].data << " ";//访问顶点
        visit[j] = 1;
        q[++rear] = j;//入队
      }
      p = p->next;
    }
  }
}

void BFS2_All(GraphAdjList &g) {
  for (int i = 0; i < g.vexnum; i++) {
    if (visit[i] == 0) {
      BFS2(g, i);
    }
  }
}

// 清除
void clear(GraphAdjList &g) {
  for (int i = 0; i < g.vexnum; i++) {
    visit[i] = 0;
  }
}

int main() {
  int x = 0;
  GraphAdjList g;
  Creat(g);
  cout << "输入想要从哪一个位置出发" << "\n";
  cin >> x;
  Print(g);

    // 初始化visit数组
    clear(g);
    cout << "深度优先遍历(递归)"
         << "\n";
    DFS(g, x);
    DFS_All(g);
    cout << "\n";

    // 初始化visit数组
    clear(g);
    cout << "深度优先遍历(非递归)"
         << "\n";
    DFS2(g, x);
    DFS2_All(g);
    cout << "\n";

    // 初始化visit数组
    clear(g);
    cout << "广度优先遍历" << "\n";
    BFS2(g,x);
    BFS2_All(g);
    cout << "\n";
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值