A simple implemention
Use the backtracking to get all clusters, let's start from (0,0) as an example, we first check if (0,0) is 1, if so, check its neighbors one by one. If one of the neighbors is 1, move there and check in the same way. this process doesn't stop until the position's four direction neighbors are all 0 or visited.
To record the position we visited, we need a flag map which has the same size as origin array.
Besides, to draw each cluster, during the backtracking, we record each postion at the same time, I choose a set of list to save all positions in a cluster.
here is all code, including test case you post
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define MAX_COL 6
#define MAX_ROW 5
#define MAX_SIZE (MAX_COL * MAX_ROW)
int a[5][6] = {
1, 1, 0, 0, 0, 0,
1, 1, 0, 1, 0, 0,
1, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 1,
0, 0, 1, 0, 1, 1,
};
int dir_x[4] = {0, 1, 0, -1};
int dir_y[4] = {1, 0, -1, 0};
struct point {
int x;
int y;
};
struct node {
struct point pos;
struct node *next;
};
struct node* cluster_set[MAX_SIZE];
int cluster_set_index = 0;
int is_inside(int height, int width, int i, int j)
{
if (0 <= j && j < width && i >= 0 && i < height)
return 1;
return 0;
}
int cluster_check(int (*matrix)[MAX_COL], int height, int width, int row, int col, int (*flag_matrix)[MAX_COL], struct node* head)
{
int i, tmp_x, tmp_y;
flag_matrix[row][col] = 1;
for (i = 0; i < 4; i++)
{
tmp_x = row + dir_x[i];
tmp_y = col + dir_y[i];
if (is_inside(height, width, tmp_x, tmp_y) && matrix[tmp_x][tmp_y] && !flag_matrix[tmp_x][tmp_y]) {
flag_matrix[tmp_x][tmp_y] = 1;
struct node *new_node = (struct node*)malloc(sizeof(struct node));
assert(new_node != NULL);
new_node -> pos.x = tmp_x;
new_node -> pos.y = tmp_y;
new_node -> next = NULL;
head -> next = new_node;
cluster_check(matrix, height, width, tmp_x, tmp_y, flag_matrix, new_node);
}
}
}
int cluster_count(int (*matrix)[MAX_COL], int height, int width)
{
int count = 0, i, j;
int flag_matrix[MAX_ROW][MAX_COL] = {0};
for (i = 0; i < height; i++)
for (j = 0; j < width; j++)
{
if (matrix[i][j] && !flag_matrix[i][j]) {
count++;
struct node *new_node = (struct node*)malloc(sizeof(struct node));
assert(new_node != NULL);
new_node -> pos.x = i;
new_node -> pos.y = j;
new_node -> next = NULL;
cluster_set[cluster_set_index++] = new_node;
cluster_check(matrix, height, width, i, j, flag_matrix, new_node);
}
}
return count;
}
void print_cluster(int (*map)[MAX_COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
printf("%2d ", map[i][j]);
printf("\n");
}
printf("\n");
}
int main()
{
printf("total clusters: %d\n", cluster_count(a, 5, 6));
int i, cluster_map[MAX_ROW][MAX_COL] = {0};
struct node *tmp;
for (i = 0; i < cluster_set_index; i++)
{
tmp = cluster_set[i];
while (tmp != NULL) {
printf("(%d, %d)", tmp->pos.x, tmp->pos.y);
cluster_map[tmp->pos.x][tmp->pos.y] = 1;
tmp = tmp -> next;
}
printf("\n");
print_cluster(cluster_map, MAX_ROW, MAX_COL);
memset(cluster_map, 0x00, sizeof(int)*MAX_ROW*MAX_COL);
}
}
and here is the running results, just ignore the infomation you don't need
total clusters: 4
(0, 0)(0, 1)(1, 1)(1, 0)(2, 0)
1 1 0 0 0 0
1 1 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
(1, 3)
0 0 0 0 0 0
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
(2, 5)(3, 5)(4, 5)(4, 4)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 1
0 0 0 0 0 1
0 0 0 0 1 1
(3, 2)(4, 2)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 1 0 0 0