给定一个二维数组,1表示可用,0表示不可用。节点可以上下左右连通,计算出数组中连通的路径的个数。
如:
int lands[ROW][COL]={
{0,1,1,0,1,0,0},
{0,0,1,0,1,0,0},
{0,0,1,0,0,0,0},
{0,0,1,1,1,0,0},
{0,1,0,0,1,0,0},
{0,1,1,0,0,0,0},
{0,1,1,0,1,0,0}
} ;
思路:
建立起一个连通的关系,让节点可以指向自己的四个方向的其他节点。
然后:
1、用深度搜索的方法
2、用广度搜索的方法
搜索的程序如下:
/*
二维数组,表示一个地图,数组某位如果是0,表示是海洋,如果是1,表示是陆地。
陆地的上下左右可以互通。
计算共有多少陆地,每块陆地的大小。
*/
#include <iostream>
using namespace std;
static const int ROW=7;
static const int COL=7;
int lands[ROW][COL]={
{0,1,1,0,1,0,0},
{0,0,1,0,1,0,0},
{0,0,1,1,0,0,0},
{0,0,1,1,1,1,0},
{0,1,0,1,1,1,0},
{0,1,1,0,0,0,0},
{0,1,1,0,1,0,0}
} ;
class node{
public:
node(int r,int c,int v):row(r),col(c),value(v){
visited=false;
this->preRowNode=NULL;
this->nexRowNode=NULL;
this->leftNode=NULL;
this->rightNode=NULL;
}
bool isVisited(){
return this->visited;
}
void setVisited(bool vi){
this->visited=vi;
}
int getValue(){
return this->value;
}
void setValue(int value){
this->value=value;
}
int getRow(){
return this->row;
}
int getCol(){
return this->col;
}
node *preRowNode;
node *nexRowNode;
node *leftNode;
node *rightNode;
private:
bool visited;
int value;
int row;
int col;
};
const static int stackSize=100;
template <class T>
class queue{
public :
queue(){
head=0;
tail=0;
}
void enqueue(T a){
data[tail++]=a;
}
T dequeue(){
if(head<tail){
return data[head++];
}else{
return NULL;
}
}
bool isEmpty(){
return head==tail;
}
int getSize(){
return tail-head;
}
void clear(){
head=tail=0;
}
private :
T data[stackSize];
int head;
int tail;
};
template <class T>
class stack{
public:
stack(){
top=0;
}
void push(T a){
data[top++]=a;
}
T pop(){
return data[--top];
}
T getPop(){
return data[top-1];
}
T getPoi(int poi){
if(poi>=0&&poi<top){
return data[poi];
}
}
bool isEmpty(){
return top==0;
}
int getSize(){
return top;
}
void clear(){
top=0;
}
private:
T data[stackSize];
int top;
};
class Path{
public:
void printPath(){
int i=0;
node *n;
for(i=0;i<pathNodes.getSize()-1;i++){
n=pathNodes.getPoi(i);
cout<<"("<<n->getRow()<<","<<n->getCol()<<"), ";
}
n=pathNodes.getPop();
if(n!=NULL){
cout<<"("<<n->getRow()<<","<<n->getCol()<<")\n";
}
}
void addNode(node *n){
pathNodes.push(n);
}
void clear(){
pathNodes.clear();
}
private :
stack<node*> pathNodes;
};
/**
扫描数组,建立node网
*/
void bulidRelation(stack<node*> *nodes){
int i,j;
int r=ROW;
int c=COL;
node *n,*n2;
int v;
for(i=0;i<r;i++){
for(j=0;j<c;j++){
v=lands[i][j];
n=new node(i,j,v);
//跟左边的node建立关系
if(j>0){
n2=nodes->getPop() ;
n2->rightNode=n;
n->leftNode=n2;
}
//跟上行的node建立关系
if(i>0){
n2=nodes->getPoi((i-1)*c+j);
n2->nexRowNode=n;
n->preRowNode=n2;
}
nodes->push(n);
}
}
}
/*
深度优先的搜索。
*/
void depthFirst(stack<node*> *allnodes){
cout<<"-----------------DFS----------------\n";
//初始化这个栈
stack<node*> workstack;
node *n,*n2;
Path path;
int idx=allnodes->getSize()-1;
cout<<"idx="<<idx<<"\n";
for(;idx>=0;idx--){
n=allnodes->getPoi(idx);
if(n->isVisited() || n->getValue()==0){
continue;
}
workstack.push(n);
n->setVisited(true);
cout<<"DFS begin a new path\n";
path.clear();
while(!workstack.isEmpty()){
n=workstack.pop();
path.addNode(n);
// cout<<"("<<n->getRow()<<","<<n->getCol()<<") -> ";
//寻找该node的前后左右,放进工作栈
n2=n->preRowNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workstack.push(n2);
n2->setVisited(true);
}
n2=n->nexRowNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workstack.push(n2);
n2->setVisited(true);
}
n2=n->leftNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workstack.push(n2);
n2->setVisited(true);
}
n2=n->rightNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workstack.push(n2);
n2->setVisited(true);
}
}
path.printPath();
}
}
/*
广度优先的搜索。
*/
void boradFirst(stack<node*> *allnodes){
cout<<"-----------------BFS----------------\n";
queue<node*> workNodes;
node *n,*n2;
Path path;
int idx=allnodes->getSize()-1;
cout<<"idx="<<idx<<"\n";
for(;idx>=0;idx--){
n=allnodes->getPoi(idx);
if(n->getValue()==0 || n->isVisited()){
continue;
}
workNodes.clear();
path.clear();
cout<<"BFS begin a new path\n";
workNodes.enqueue(n);
n->setVisited(true);
while(!workNodes.isEmpty()){
n=workNodes.dequeue();
path.addNode(n);
n2=n->preRowNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workNodes.enqueue(n2);
n2->setVisited(true);
}
n2=n->nexRowNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workNodes.enqueue(n2);
n2->setVisited(true);
}
n2=n->leftNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workNodes.enqueue(n2);
n2->setVisited(true);
}
n2=n->rightNode;
if(n2!=NULL && !n2->isVisited() && n2->getValue()>0){
workNodes.enqueue(n2);
n2->setVisited(true);
}
}
path.printPath();
}
}
int main(){
stack<node*> allNodes;
bulidRelation(&allNodes);
//DFS
depthFirst(&allNodes);
int idx=allNodes.getSize()-1;
node *n;
for(;idx>=0;idx--){
n=allNodes.getPoi(idx);
n->setVisited(false);
}
//BFS
boradFirst(&allNodes);
//destroy
while(!allNodes.isEmpty()){
n=allNodes.pop();
delete n;
}
}