上午
写了三个链表题目,分别运用到的是双向链表、合并链表跟链表遍历。
由于代码过长,接下来只把主要函数展示出来:
1,这个是双向链表实现
void cirle(int se)
{
int cnt=1;
while(tail->link!=NULL)
tail=tail->link;
tail->link=head;
tail=tail->link;
cnt=1;
while(cnt<=se-1)
{
tail=tail->link;
cnt++;
}
cnt=1;
if(flag==0)
while(cnt<=m+1)
{
printf("%d ",tail->data);
tail=tail->link;
cnt++;
}
else
while(cnt<=m)
{
printf("%d ",tail->data);
tail=tail->link;
cnt++;
}
}
嗯……其他的代码好像太简单了没保存……
另外两个就算了,都是简单的东西。
我还稍微看了看c++的书,学会了#include <iosteam>和cin、cout……
哦,还有using namespace std;
下午
学习dfs和回溯算法,并试着在题目上使用,效果并不理想……
对于回溯这东西啊,不是很能搞懂,倒也知道回溯是什么意思和是怎么来的,可我写的话,写个半天都没写出来,看来还是得多练练。
举个例吧,就今天写的一个回溯题。
题目是这个:
我本来想的是用一个变量存数,然后一个一个的加上去,直到数目达到了指定数,然后输出。也是用到回溯,因为它有加的数的变化,所以的确是要用到回溯去适应题目。结果没写出来……后来我又改变想法,用一个数组记录要加的数,同一个数加了几次,那数组下标中的元素就是几,就类似桶排,不过只用来计数,后来意识到这想法不是很机灵,而且还是没实现出来……
咳咳,看了一下题解。学到一本书上的实现方法,代码如下:
(咳咳,备注是我理解的意思)
#include <stdio.h>
int n,book[20]={1};
void print(int a)
{
for(int i=1;i<=a-1;i++)
printf("%d+",book[i]);
printf("%d\n",book[a]);
}
void seek(int c,int a)
{
for(int i=book[a-1];i<=c;i++)//循环,得到c被拆分出的数
{
if(i>=n)
break;
book[a]=i;
c-=i;//将被拆分掉的数从c中减去
if(c==0)//若c已等于0则代表已经拆分完
print(a);
else seek(c,a+1);//不等0则继续拆分
c+=i;//回溯,将已被拆分掉的数加回
}
}
int main()
{
scanf("%d",&n);
seek(n,1);
}
它是使用指定的数字去拆分,每拆分一个数就减去它,等到指定的数字已经是0了,就代表拆分完成……嗯,挺好的。
然后所谓回溯,就是将它已经被拆分掉的数字重新加回来,然后下次拆分的数字是上一次的+1,这样就实现了每一组组成数目的不同且呈现递增排列,因为是函数自己调用自己,所以会出现不同的线路,所以每种情况就都考虑到了,而且它用了一个一维数组存储被拆分出来的数,这样输出也变得简单些。它的a只有在自调用时才会改变值,而在for循环中并不更改,所以这就可以在一次print之后从后面更改其他的值,因为自始至终是使用a来赋值,在每条线路之后可以覆盖赋值,从而达到自后更改的目的。真就很精妙。
嗯,多练练,多练练。
晚上
尝试写“八皇后”,尝试失败。
尝试写“计算池塘数”,失败。
尝试写“两链表去重”,失败。
明日计划
明天继续学习回溯和dfs,要能在题目中使用并完成题目,把没写出来的题目做出来。