关于求01串组成的岛屿系列问题

给出一个n行m列的01串,例如:

0 1 1 0 1

0 1 0 0 1

1 1 0 1 0

0 0 1 1 0

则该地图上有三个岛屿面积分别为5,2,3;

那么我们应该应该如何去求这些岛屿的个数以及岛屿的面积呢?

我有这样一个想法,我们循环遍历这个二维数组,当遇到1时进行“登陆“,所谓“登陆“即用DFS或者BFS去把所有的1置为一个标记值,然后接着循环遍历二维数组,最后对进行DFS或者BFS次数进行计数,这个次数就是岛屿的个数;在进行BFS时我用了顺序队,这样在遍历完成后顺序队里的元素个数即1的个数也就是岛屿的面积;

在BFS或者DFS时,为了不走重复的路,在进队或者进栈时把地图MAP对应的位置标记为-1,即这个路已经走过;

下面是我的代码:由于本人水平有限,代码有错误的地方请指出;


#include <stdio.h>
#include <stdlib.h>
#include<malloc.h>
#define MAX_SIZE 100 // 栈(队列)的最大长度;


int BFS(int **MAP, int x, int y,int n, int m);
int DFS_1(int **MAP, int x, int y,int n, int m);
void DFS_2(int **MAP, int x, int y, int n, int m,int *temp);
typedef struct node_que {
    int x;
    int y;
} QUEUE; 
typedef struct node_stock{
    int x;
    int y;
    int dir; // 寻找方向
}STOCK; 
int main()
{
    int m, n,  i, k; // n行m列
    int max = 0, temp;
    int num_of_island = 0;
    printf("please enter n and m,  (n行m列):");
    scanf("%d",&n);
    scanf("%d",&m);
    int **MAP = (int**)malloc(n*sizeof(int*));
    for(i = 0; i < n;i++)
        MAP[i] = (int*)malloc(m*sizeof(int));
    for(i = 0; i < n ; i++){
        for(k = 0; k < m; k++){
            scanf("%d",&MAP[i][k]);
        }
    }
     for(i = 0; i < n ; i++){
        for(k = 0; k < m; k++){
            if(MAP[i][k] == 1){
                temp = BFS(MAP,i,k,n,m);
                if(max < temp)
                    max = temp;
                num_of_island++;
            }
        }
    }
    for(i = 0; i < n; i++){
        for (k = 0; k < m;k++){
            if(MAP[i][k] == 2)
                MAP[i][k] = 1;
        }
    }
    printf("(BFS)最大岛屿的面积(即1的个数)是  = %d\n",max);
    printf("(BFS)岛屿的总个数 =  %d\n",num_of_island);


    max = 0;
    num_of_island = 0;
    for(i = 0; i < n ; i++){
        for(k = 0; k < m; k++){
            if(MAP[i][k] == 1){
                temp = DFS_1(MAP,i,k,n,m);
                if(max < temp)
                    max = temp;
                num_of_island++;
            }
        }
    }
    for(i = 0; i < n; i++){
        for (k = 0; k < m;k++){
            if(MAP[i][k] == 2)
                MAP[i][k] = 1;
        }
    }
    printf("(非递归DFS)最大岛屿的面积(即1的个数)是  = %d\n",max);
    printf("(非递归DFS)岛屿的总个数 =  %d\n",num_of_island);


    max = 0;
    num_of_island = 0;
    for(i = 0; i < n ; i++){
        for(k = 0; k < m; k++){
            if(MAP[i][k] == 1){
                temp = 1;
                DFS_2(MAP,i,k,n,m,&temp);
                if(max < temp)
                    max = temp;
                num_of_island++;
            }
        }
    }
    for(i = 0; i < n; i++){
        for (k = 0; k < m;k++){
            if(MAP[i][k] == 2)
                MAP[i][k] = 1;
        }
    }
    printf("(递归DFS)最大岛屿的面积(即1的个数)是  = %d\n",max);
    printf("(递归DFS)岛屿的总个数 =  %d\n",num_of_island);
    for(i = 0; i < n;i++)
        free(MAP[i]);
   free(MAP);
   return 0;

}

// BFS

int BFS(int **MAP, int x, int y,int n, int m)
{
    QUEUE St[MAX_SIZE];
    int front = -1;
    int rear = -1;
    St[++rear].x = x;
    St[rear].y = y;
    QUEUE temp;
    while(front != rear){
        temp.x = St[++front].x;
        temp.y = St[front].y;
        MAP[temp.x][temp.y] = 2;
        if(temp.y < m- 1 && MAP[temp.x][temp.y + 1] == 1){
            St[++rear].x = temp.x;
            St[rear].y = temp.y + 1;
            MAP[St[rear].x][St[rear].y] = -1;
        }
        if(temp.x < n- 1 && MAP[temp.x + 1][temp.y ] == 1){
            St[++rear].x = temp.x + 1;
            St[rear].y = temp.y;
            MAP[St[rear].x][St[rear].y] = -1;
        }
        if(temp.y > 0 && MAP[temp.x][temp.y - 1] == 1){
            St[++rear].x = temp.x;
            St[rear].y = temp.y - 1;
            MAP[St[rear].x][St[rear].y] = -1;
        }
        if(temp.x > 0 && MAP[temp.x - 1][temp.y] == 1){
            St[++rear].x = temp.x - 1;
            St[rear].y = temp.y;
            MAP[St[rear].x][St[rear].y] = -1;
        }
    }
    return front + 1;


}

// 非递归DFS
int DFS_1(int **MAP, int x, int y,int n, int m)
{
    STOCK St[MAX_SIZE];
    int top = -1;
    int find, x_1, y_1, dir, area_of_island = 1;
    St[++top].x = x;
    St[top].y = y;
    MAP[x][y] = -1;
    St[top].dir = 1;
    dir = St[top].dir;
    while( top > -1){
        find = 0;
        while(dir < 5 && find == 0){
            switch(dir){
                case 1:
                    x_1 = St[top].x;
                    y_1 = St[top].y + 1;
                    if( y_1 < m && MAP[x_1][y_1] == 1)
                        find = 1;
                    else
                        dir++;
                    break;
                case 2:
                    x_1 = St[top].x - 1;
                    y_1 = St[top].y;
                    if(x_1 >= 0 && MAP[x_1][y_1] == 1)
                        find = 1;
                    else
                        dir++;
                    break;
                case 3:
                    x_1 = St[top].x;
                    y_1 = St[top].y - 1;
                    if( y_1 >= 0 && MAP[x_1][y_1] == 1)
                        find = 1;
                    else
                        dir++;
                    break;
                case 4:
                    x_1 = St[top].x + 1;
                    y_1 = St[top].y;
                    if(x_1 < n && MAP[x_1][y_1] == 1)
                        find = 1;
                    else
                        dir++;
                    break;
            }
        }
        if(find == 1){
            St[top].dir = dir;
            St[++top].x = x_1;
            St[top].y = y_1;
            MAP[x_1][y_1] = -1;
            dir = 1;
            area_of_island++;
        }
        else{
            MAP[St[top].x][St[top].y] = 2;
            dir = St[--top].dir + 1;
        }
    }
    return area_of_island;
}

// 递归DFS
void DFS_2(int **MAP, int x, int y, int n, int m,int *temp)
{
    MAP[x][y] = -1;
    if( y < m - 1 && MAP[x][y+1] == 1){
            (*temp)++;
            DFS_2(MAP,x,y+1,n,m,temp);
    }
    if( x > 0 && MAP[x - 1][y] == 1){
            (*temp)++;
            DFS_2(MAP,x - 1,y,n,m,temp);
    }
    if( y > 0 && MAP[x][y-1] == 1){
            (*temp)++;
            DFS_2(MAP,x,y-1,n,m,temp);
    }
    if( x < n - 1 && MAP[x + 1][y] == 1){
            (*temp)++;
            DFS_2(MAP,x +1,y,n,m,temp);
    }
    MAP[x][y] = 2;

}


运行结果:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值