反思:最近写题发现前面学的那些语法太长时间不看,不用,就忘了,而且,学的很浅,不能够学以致用。这周主要是快排,递归,还有二分答案的应用,但是大多数的题目都要依赖着答案才能写出来,要不然这个知识点也用不起来。
一:之前的话学过快速排序,太久不看就忘记怎么写了。快速排序在时间上比sort要快得多。下面这个题目是快速排序的模板题目:P1177 【模板】快速排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这道题目我们采用两种方法,一种是快排,一种是下面我们要总结的归并排序。
首先是快速排序的写法。
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int a[100005];
void q_sort(int l,int r)
{
int mid=a[(l+r)/2];//重点:这里的mid其实可以任意,可取a[l],a[r]等等,但是往往数据大的时候会超时,因此我们让mid=a[(l+r)/2]。
int i=l;int j=r;
do{
while(a[j]>mid) j--;
while(a[i]<mid) i++;
if(j>=i)
{
swap(a[i],a[j]);
j--;
i++;
}
}while(j>=i);
if(l<j) q_sort(l,j);
if(i<r) q_sort(i,r);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
q_sort(1,n);
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
二:归并排序的大致思路是讲一个大的数组先逐个的切分成单个,然后利用递归的思想,能够回退回去,从而保证一级一级比较,思想如图所示:
代码如下:
#include<bits/stdc++.h>
using namespace std;
int n;
int a[100005];
int tmp[100005];//临时数组
void m_sort(int a[],int l,int r)
{
if(l>=r) return;
int mid=(l+r)/2;
m_sort(a,l,mid); m_sort(a,mid+1,r);//先全部进行分割好
int k=0;int i=l;int j=mid+1;
while(i<=mid&&j<=r)
{
if(a[i]<a[j]) tmp[k++]=a[i++];
else tmp[k++]=a[j++]; //先左右比较
}
while(i<=mid) tmp[k++]=a[i++];//左边剩下的
while(j<=r) tmp[k++]=a[j++];//右边剩下的
for(int i=l,j=0;i<=r;i++,j++) a[i]=tmp[j];//排好序,再将临时数组里面的数据写回来
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
m_sort(a,1,n);
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
三:这两天都是觉得二分学会了,但是并没有学好,还是有很多东西不够理解,还是要在写题目时候好好理解写,但是可以确定的是,二分在写框架的时候是这样的。
while(l<=r)
{
int mid=(l+r)/2;
if(search(mid)) l=mid+1;
else r=mid-1;
}
可能遇到的条件还是要具体分析。