首页 > 编程语言 >DFS算法的非递归遍历分析

DFS算法的非递归遍历分析

时间:2023-11-27 22:35:30浏览次数:44  
标签:遍历 Ver 递归 int DFS return printf visited true

两种写法,一个是边表顶点号全部压栈,一个是类似后序非递归遍历

1、

void DFS(Graph G,int i)
{
    int p,w;
    Stack S;
    InitStack(S);
    Push(S,i);
    visited[i]=true;
    while(!isEmpty(S))
    {
        Pop(S,p);
        printf("%d    ",G.Ver[p].num);
        for(w=FirstNeighbor(G,p);w>=0;w=NextNeighbor(G,p,w))
        {
            if(!visited[w])
            {
                Push(S,w);
                visited[w]=true;
            }
        }
    }
}

2、有一个回头的操作,但是不如第一种直接

void DFS(Graph G,int i)
{
    int p,w;
    Stack S;
    InitStack(S);
    printf("%d    ",G.Ver[i].num);
    visited[i]=true;
    Push(S,i);
    while(!isEmpty(S))
    {
        GetTop(S,p);
        w=FirstNeighbor(G,p);
        if(w!=-1&&!visited[w])
        {
            Push(S,w);
            visited[w]=true;
            printf("%d    ",G.Ver[w].num);    
        }
        else
        {
            Pop(S,p);
            if(isEmpty(S))
                break;
            GetTop(S,w);
            w=NextNeighbor(G,w,p);
            if(w!=-1&&!visited[w])
            {
                printf("%d    ",G.Ver[w].num);
                visited[w]=true;
                Push(S,w);
            }
        }
    
    }            
} 

完整代码

#include <stdio.h> 
#include <stdlib.h> 
#define MaxSize 20

typedef int Elem ;
                                        //邻接表 
typedef struct ArcNode{        //边表 
    int adjvex;                //边表中是顶点号!! 
    struct ArcNode *next;
}ArcNode;

typedef struct VNode{        //主表 
    Elem num;                //主表中是顶点值!! 
    struct ArcNode *first; 
}VNode,AdjList[MaxSize];

typedef struct{                    
    AdjList Ver;
    int vernum,edgenum;
}Graph;

typedef struct{
    int data[MaxSize];
    int top;
}Stack;

void InitStack(Stack &S)
{
    S.top=-1;
}

bool isEmpty(Stack S)
{
    if(S.top==-1)
        return true;
    return false;
}

bool isFull(Stack S)
{
    if(S.top==MaxSize-1)
        return true;
    return false;
}

bool Push(Stack &S,int p)
{
    if(isFull(S))
        return false;
    S.data[++S.top]=p;
    return true;
}

bool Pop(Stack &S,int &p)
{
    if(isEmpty(S))
        return false;
    p=S.data[S.top--];
    return true;
}

bool GetTop(Stack S,int &p)
{
    if(isEmpty(S))
        return false;
    p=S.data[S.top];
    return true;
}

void CreateGraph(Graph &G)
{
    G.vernum=G.edgenum=0;
    printf("请输入顶点数:");
    scanf("%d",&G.vernum);
    printf("请输入主表顶点:\n");
    int i,j;
    for(i=0;i<G.vernum;i++)
        scanf("%d",&G.Ver[i].num);
    
    printf("请输入边表顶点号:\n");
    int x;
    for(i=0;i<G.vernum;i++)
    {
        G.Ver[i].first = (ArcNode*)malloc(sizeof(ArcNode));
        G.Ver[i].first->next=NULL;
        printf("%d的边表\n",G.Ver[i].num); 
        ArcNode *p=G.Ver[i].first;
        for(j=0;j<G.vernum;j++)
        {
            scanf("%d",&x);
            if(x==-1)
                break;
            else
            {
                ArcNode *node=(ArcNode*)malloc(sizeof(ArcNode));
                node->adjvex=x;
                node->next=NULL;
                p->next=node;
                p=node;
                G.edgenum++;
            }
        }
    }
}

void displayGraph(Graph G)
{
    int i,j;
    printf("顶点个数:%d\n边数:%d\n",G.vernum,G.edgenum);
    for(i=0;i<G.vernum;i++)
    {
        printf("%d    ",G.Ver[i].num);    
        ArcNode *p=G.Ver[i].first->next;
        while(p)
        {
            printf("-->%d",p->adjvex);
            p=p->next;
        }
        printf("\n");
    } 
}

int FirstNeighbor(Graph G,int x)
{
    if(G.Ver[x].first->next)
        return G.Ver[x].first->next->adjvex;
    return -1;
}

int NextNeighbor(Graph G,int x,int y)
{
    ArcNode *p=G.Ver[x].first->next;
    while(p&&p->adjvex!=y)
        p=p->next;

    if(p->next)
        return p->next->adjvex;    
    return -1;    
}

bool visited[MaxSize];

void DFS(Graph G,int i)
{
    int p,w;
    Stack S;
    InitStack(S);
    printf("%d    ",G.Ver[i].num);
    visited[i]=true;
    Push(S,i);
    while(!isEmpty(S))
    {
        GetTop(S,p);
        w=FirstNeighbor(G,p);
        if(w!=-1&&!visited[w])
        {
            Push(S,w);
            visited[w]=true;
            printf("%d    ",G.Ver[w].num);    
        }
        else
        {
            Pop(S,p);
            if(isEmpty(S))
                break;
            GetTop(S,w);
            w=NextNeighbor(G,w,p);
            if(w!=-1&&!visited[w])
            {
                printf("%d    ",G.Ver[w].num);
                visited[w]=true;
                Push(S,w);
            }
        }
    
    }            
} 

void DFS(Graph G,int i)
{
    int p,w;
    Stack S;
    InitStack(S);
    Push(S,i);
    visited[i]=true;
    while(!isEmpty(S))
    {
        Pop(S,p);
        printf("%d    ",G.Ver[p].num);
        for(w=FirstNeighbor(G,p);w>=0;w=NextNeighbor(G,p,w))
        {
            if(!visited[w])
            {
                Push(S,w);
                visited[w]=true;
            }
        }
    }
}

void DFSbyStack(Graph G)
{
    int i;
    for(i=0;i<G.vernum;i++)
        visited[i]=false;
    for(i=0;i<G.vernum;i++)
        if(!visited[i])
            DFS(G,i);
}

int main()
{
    Graph G;
    CreateGraph(G);
    printf("\n");
    displayGraph(G);
    printf("\n");
    DFSbyStack(G);
    return 0;
}

 

标签:遍历,Ver,递归,int,DFS,return,printf,visited,true
From: https://www.cnblogs.com/simpleset/p/17860696.html

相关文章

  • Linux安装fastdfs图片服务器
    1、阿里云安装centos7服务器得到用户名密码和ip后用securCrt连接工具链接远程主机2、安装fastdfs图片服务器(1)上传需要的压缩包libfastcommon-common.zip(依赖工具包)  FastDFS_v5.05.tar.gz(源码)  fastdfs-nginx-module_v1.16.tar.gz(与nginx连接的模块)nginx1.8版本  ......
  • delphi 遍历集合类型
    遍历集合类型代码通过for-in循环遍历usesSystem.TypInfo;procedureTForm1.Button1Click(Sender:TObject);varvAnchors:TAnchors;vAnchor:TAnchorKind;beginvAnchors:=[akLeft,akTop,akBottom];forvAnchorinvAnchorsdobeginMemo1.Lines.......
  • Java 反射+递归 实现数据聚合发布的配置化
    大致是GraphQL的思路分开配置接口数据结构和数据实体的元数据支持列表查询,支持多层级的数据聚合参数选叶子节点就行,后续可以把参数用JS实现一个选择树状结构的UI,生成出查询字符串来,或者按照字段分配权限给租户异常处理的不太好,有待继续调试不支持数据权限,只支持根据聚合根向......
  • map 接口的遍历
    packagecom.wxledu.map_;importjava.util.*;@SuppressWarnings({"all"})publicclassMapFor{publicstaticvoidmain(String[]args){Mapmap=newHashMap();map.put("邓超","孙俪");map.put("......
  • 用函数递归求阶乘
    #include<stdio.h>intfactorial(intx){  if(x<=1)    return1;  else  {    x=x*factorial(x-1);    return(x);  }  }intmain(){  intn,m;  printf("请输入n:");  scanf_s("%d",&n......
  • DFS序和欧拉序的降维打击
    1.DFS序和时间戳1.1DFS序定义:树的每一个节点在深度优先遍历中进、出栈的时间序列。如下树的dfs序就是[1,2,8,8,5,5,2,4,3,9,9,3,6,6,4,7,7,1]。下图为生成DFS的过程。对于一棵树进行DFS序,除了进入当前节点时对此节点进行记录,同时在回溯到当前节点时对其也记录一下,所以DF......
  • Java算法练习—递归/回溯
    递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能将原本的问题分解为更小的子问题,这是使用递归的关键。如果是线型递归,子问题直接回到父问题......
  • dfs-单词匹配2
    题目描述在一个字符矩阵中,可把横向或竖向连续相邻的字符、按顺序组成一个单词,例如下图所示的XE、ACX、STJIIE给定一个字符矩阵charMatrix和目标单词列表words,请计算这个字符矩阵可以组成多少个words中的单词,并返回这个数量:矩阵中每个格子的字符,对于同一个单词不能重复使......
  • dfs思想方式
    dfs深度优先搜索:一条路走到黑基本模型:Returntypedfs(参数){判断边界(返回)扩展状态dfs下一步返回}dfs+记忆返回值=记忆化搜索  classSolution{public:intminPathCost(vector<vector<int>>&grid,vector<vector<int>>&moveCost){......
  • acwing 第 130 场周赛  (前缀和,dfs,对不同边的处理)
      #include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<climits>usingnamespacestd;typedeflonglongLL;constintN=5010;intn;inta[N];LLs[N];LLget(intl,intr){return......