DFS+BFS

DFS

深度优先搜索,类似于树的先序遍历
(第一次学DFS是在图中遇到的,那就先回顾下图里的DFS)

代码(以邻接表为例)

基于邻接表的复杂度为O(n+e),而基于邻接矩阵要O(n方)

void DFS_Visit(Graph &G)
{
	for(int i=0;i<G.vexnum;i++)
	{
		visit[i]=false;//初始化
	}
	for(int i=0;i<G.vexnum;i++)
	{
		if(visit[i]==false)
		{
			DFS(G,i);
		}
	}
	//如果图有多个连通分量,就需要多个节点分别起始DFS
	
}
void DFS(Graph &G,int index)
{
		ArcNode *p;
		visit[index]=True;
		//每个节点遍历一次就好了
		p=G->VexNode[index].firstarc;
		while(p)
		{
			if(visit[p->adjvex]==false)
			{
				DFS(G,p->adjvex);
			}
			p=p->nextarc;
		}
}

DFS做全n个数排列

int main()
{
	DFS(0);
	return 0;
}
void DFS(int index)
{
	if(index==n)
	{
		for(int i=0;i<n;i++)
		{
			cout<<a[i];
		}
		return ;
	}
	for(int i=0;i<n;i++)
	{
		if(vis[i]==0)
		{
			vid[i]=1;
			a[depth]=i;
			DFS(depth+1);
			vis[i]=0;
		}
	}
}

例题

给定n个正整数,判断是否可以从中选取若干个正整数,使他们的和恰为整数k

include<bits/stdc++.h>
using namespace std;
int k;
bool DFS(int index,int sum)
{
	if(sum==k)
	{
		return true;
	}
	//要a[index]
	if(DFS(index+1,sum+a[index])==true)
		return true;
	//不要a[index]
	if(DFS(index+1,sum)==true)
		return true;
	return false;
}
int main()
{
	int n;
	cin>>n>>k;
	int *a=(int *)malloc(sizeof(int)*n);
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	if(DFS(0,0)==true)
	{
		cout<<"YES";
	}
	else
		cout<<"NO";
	return 0;
}

Lake Counting

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int **N;
char **G;
int dx[8]={0,1,1,1,0,-1,-1,-1};
int dy[8]={1,1,0,-1,-1,-1,0,1};
int n,m;
void DFS(int x,int y)
{
    N[x][y]=1;
    int nx,ny;
    for(int i=0;i<8;i++)
    {
        nx=x+dx[i];
        ny=y+dy[i];        
        if(nx>=0 && nx<n && ny>=0 && ny<m &&N[nx][ny]==0&&G[nx][ny]=='W')
        {
            DFS(nx,ny);
        }
    }
}
int main()
{
    cin>>n>>m;
    G=(char **)malloc(sizeof(char *)*n);
    N=(int **)malloc(sizeof(int *)*n);
    for(int i=0;i<n;i++)
    {
        G[i]=(char *)malloc(sizeof(char)*m);
        N[i]=(int *)malloc(sizeof(int)*m);
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>G[i][j];
            N[i][j]=0;
        }
    }
    int flag=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(N[i][j]==0&&G[i][j]=='W')
            {
                DFS(i,j);
                flag++;
            }
        }
    }   
    cout<<flag;
}

BFS

广度优先搜索,类似于树的层次遍历

代码

void BFS_visit(Graph &G)
{
	for(int i=0;i<G.vexnum;i++)
	{
		visit[i]=false;//初始化
	}
	for(int i=0;i<G.vexnum;i++)
	{
		if(visit[i]==false)
		{
			BFS(G,i);
		}
	}
	//如果图有多个连通分量,就需要多个节点分别起始BFS
}
void BFS(Graph G,int index)
{
	ArcNode *p;
	int Qu[MAX_V],front=rear=0;
	Qu[rear++]=index;//先赋值rear再自动加一,起始点入队
	visit[index]=true;
	while(front!=rear)
	{
		i=Qu[front];
		front=(front+1)%MAX_V;
		cout<<G.vex[i];
		p=G->VexNode[i].firstarc;
		while(p)
		{
			if(visit[p->adjex]==false)
			{
				Qu[rear]=p->adjex;
				rear=(rear+1)%MAX_V;
				visit[p->adjex]=true;
			}
			p=p->nextarc;
		}
	}
	
}

BFS找迷宫入口到出口的最短路径

int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<N;j++)
		{
			cin>>s[i][j];
			if(s[i][j]=='S')
			{
				Sx=i;
				Sy=j;
				step[i][j]=0;
				//起点
			}
			step[i][j]=-1;
		}
	}
	queque<node> q;
	//get到一种初始化node的方法
	q.push(node{Sx,Su});
	int ans=-1;
	while(q.size()>0)
	{	
		int x=q.front().x;
		int y=q.front().y;
		q.pop();
		for(int i=0;i<4;i++)
		{
			int newx=x+dx[i];
			int newy=y+dy[i];
			if(newx>0 && newx<n &&newy>0 && newy<m &&step[newx][newy]=-1 &&s[newx][newy]!='#' )
			{
			//这种累加的形式可以记录长度ei
				step[newx][newy]=step[x][y]+1;
				if(s[newx][newy]=='G')
				{
					ans=step[newx][newy];
					break;
				}
				q.push(node{newx,newy});
			}
		}
		if(ans!=-1)break;
	}
	cout<<ans;
	
	
}

记忆化搜素

在搜索过程中会有很多重复计算,故可以记录下来一些结果(空间换时间)
举例:斐波那契数列

int fib(int n)
{
//dp初始化全部为-1
	if(dp[n]!=-1)return dp[n];
	if(n==0||n==1)return dp[n]=1;
	return dp[n]=fib(n-1)+fib(n-2);

}

C++补充知识

c++中,内存分为5个区,分别为栈,堆,自由存储区,全局/静态存储区,常量存储区

各种变量

(后两行写反了)
在这里插入图片描述

由编译器在需要时分配,不需要时自动清除的变量的存储区,通常为局部变量,函数参数等。

由new分配的内存块,由程序控制其释放,如果程序没有释放,程序结束后,操作系统会自动回收。

自由存储区

由malloc等分配的内存块,和堆相似

全局、静态存储区

全局变量和静态变量被分配到同一块内存中

常量存储区

存放常量

例子

void ex() 
{
	 int* p=new int[5]; 
}   

该函数在栈中存放了一个指向堆内存的指针p。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值