算法期末备考-第1练
考虑到 大家针对备考 算法无从下手。
同时算法是最后一门考试科目,可能复习比较匆忙就考试了。
从今天开始每天进行一练,希望大家每天花上至少一个小时来复习,只要大家重视起这门课,就不会挂科。
算法是以理解为基础。
“理解是最好的记忆”
不要背代码,不要背代码,不要背代码。
等你理解算法核心后,做题和复习起来才会胸有成竹
内容主要分为
1、掌握算法基本思路
2、历年真题
3、课后习题
如果发现代码有错误或者有疑问请及时联系我。
放在博客上,主要是因为比较容易修改。
不用光顾着看,大脑非常容易欺骗自己,大家必须动手实践一下。
道理就好比记单词。
建议:
通过热身环节后,大家自己试着写一下后面的题目。
如果遇到不会才看参考代码,千万不要先入为主直接背代码,这样效率低而且容易忘。
热身环节
子集树问题
题目描述:
给定3个元素的一个集合,输出对应的所有子集的情况。
3个元素构成的子集为2^3=8种情况。
分别为“111,110,101,100,011,010,001,000”
题解:
面对子集的问题有很多种解法,其中一种方法为BFS,对于这颗搜索树来说是层次遍历。
顺带借助子集树问题来介绍一下BFS算法。
介绍
BFS 是 Breadth first Search 的首字母组合。
中文翻译回来是“宽度优先搜索”
在这个题目中就相当于"层次遍历",一层一层地遍历,其字母顺序为:“A,BC,DFGH,IJKLMNO”。
算法过程
过程中利用到了数据结构“队列”利用其先进先出的特性。
请大家拿出草稿纸模拟其中过程。
1、把根节点A放入队列。
2、弹出队首结点,同时将 队首结点的左右两个结点依次放入队列。
3、重复第二步就能实现层次遍历。
1、A
2、“A” | 'BC'
3、“B” | C'DE'
4、“C” | DE'FG'
……
图示:
弹出队首用“”表示。
新加入队列的元素用''表示。
" | " 后面的是当前队列中的元素。
前置知识:
过程中需要用到队列,在此之前必须要知道如何定义队列中元素的属性。
“属性”,其实根据题目来说的,
通常根据题目进行加属性。
如果是搜索树,以树为结构的必定要有一个变量作为层数 我常用Step来表示。
如迷宫类问题,必须有用于定位的坐标"int x,y"。
如果是背包问题,每个结点表示都是一种状态,每个背包都有自身的价值和重量。“int 价值:val,重量:w”
如果是整数变换问题,每个结点都有各自的值。“int x”
如果题目需要记录对应的路径,则定义“ char path[N]”
typedef struct Node{ int step ; char path[N]; }Node;
然后是C++库中提供的STL库中的queue
#include<queue> //对应的头文件 using namespace std; //利用STL库一定记住要写上"命名空间" <queue> //定义 queue<Node>Q; //定义存放Node类型队列,其名为"Q" //库函数 Q.push( (Node)*** ); //把Node类型变量,插入到Q的队尾 Node t = Q.front(); //将队首元素进行赋值给Node类型的变量t Q.pop(); //弹出队首元素 Q.empty(); //判断当前的队列中是否为空? 返回bool类型 , 若是真的为空,返回true,否则返回 false
算法实现的大体思路:
将队列中队首结点拿出来,判断其结点是否为叶子结点。
1、如果为叶子结点,输出叶子结点中的路径
2、否则,把自己与其相连的两个孩子结点给插入到队列后面。
然后具体套路模版上课已经讲过,如果忘记了的同学可以看看下面的代码复习一下具体过程。
1 //子集树 2 3 #include<queue> 4 #include<cstdio> 5 using namespace std; 6 7 //定义结点记录信息 8 typedef struct Node{ 9 char path[6]; 10 int step ; 11 }Node; 12 13 // BFS套路 14 void BFS(){ 15 16 //第一步:定义根节点和队列,并把根节点压入队列 17 queue<Node> Q ; 18 Node first ; 19 first.step = 0 ; 20 Q.push(first) ; 21 22 //第二步:保持队列非空 23 while( !Q.empty() ){ 24 25 //第三步:取出队首元素,别忘了同时要弹出队首元素 26 Node cur = Q.front() ; 27 Q.pop() ; 28 29 //第四步:设计 最终状态 进行的操作 30 if( cur.step == 3 ){ 31 for( int i = 1 ; i <= 3 ; i ++ ){ 32 printf("%c",cur.path[i]); 33 } 34 putchar('\n'); 35 continue ; 36 } 37 38 //第五步:设计 下一步怎么走,用"Next"来命名下一步结点,压入队尾 39 40 Node Next = cur ; 41 Next.step += 1 ; 42 43 //走左边 44 Next.path[ cur.step + 1 ] = 'L' ; 45 Q.push( Next ); 46 47 //走右边 48 Next.path[ cur.step + 1 ] = 'R' ; 49 Q.push( Next ); 50 } 51 } 52 53 int main() 54 { 55 BFS(); 56 return 0; 57 }