搜索连通的节点

给定一个二维数组,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;
	} 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值