思路:首先随机定义数组的一个数,把他当成边界值进行排序,一般是取数组中间的一个数,在这个数的左边区间寻找一个比他大的数,在这个数的右边区间寻找一个比他小的数,将这两个数进行交换,最后左边区间的数都小于他,右边的数都大于他,然后在左右区间分别递归。
参数1,待排序数组 参数二,起始索引 参数三,终止索引
private static void quick_sort(int[] q, int l, int r) {
if(l>=r) return;
int t=q[(l+r)/2],i=l-1,j=r+1;
while (i<j){
do i++; while (q[i]<t);
do j--; while (q[j]>t);
if(i<j) {
int temp=q[i];
q[i]=q[j];
q[j]=temp;
}
}
quick_sort(q,l,j);
quick_sort(q,j+1,r);
}
思路:该算法采用经典的分治策略(把一个大问题分解为若干个小的问题进而求解的过程),将数组不断一分为二,分成n份后,再按照有序数组的拼接方法,两两比较取每一份中的最小值进行拼接,对每个子数组进行拼接,这样就能保证每次的拼接结果都还是有序的最终拼接成一个之后,整个数组便都是有序的
private static void merge_sort(int[] q, int l, int r) {
if(l>=r) return;
int mid = l+r>>1;
merge_sort(q,l,mid);
merge_sort(q,mid+1,r);
int k=0,i=l,j=mid+1;
int []tmp=new int [r-l+1];
while (i<=mid &&j<=r) {
if (q[i] < q[j]) tmp[k++] = q[i++];
else tmp[k++] = q[j++];
}
while (i<=mid) tmp[k++]=q[i++];
while (j<=r) tmp[k++]=q[j++];
for(int m=l,n=0;m<=r;m++,n++ ) q[m]=tmp[n];
}
整数二分算法
二分的本质不是单调性, 单调性的题目一定可以二分, 可以二分的题目不一定有单调性
二分的本质是边界 二分法用于查找, 每次都选择答案所在的区间再次进行查找, 当区间长度为 1时, 就是答案
模板1
// 区间[l, r]被划分成 [l, mid] 和 [mid+1, r]时使用
int bsearch_1(int l, int r) {
while (l < r) {
int mid = l + r >> 1;
if (check[mid]) // check() 判断 mid是否满足性质
r = mid;
else
l = mid + 1;
}
return l;
}
模板2
// 区间[l, r]被划分成 [l, mid-1] 和 [mid, r]时使用
int bsearch_2(int l, int r) {
while (l < r) {
int mid = l + r + 1 >> 2; // 注意
if (check[mid]) // check() 判断 mid是否满足性质
l = mid;
else
r = mid - 1;
}
return l;
}
如何选择模板
根据 check(mid)来判断 r和 l的取值范围 根据取值范围选择 mid是否有 + 1操作 如果mid满足条件在左边, r = mid, mid选择 不 +1 如果mid满足条件在右边, l = mid, mid选择 +1
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
double n= sc.nextDouble();
double eps=1e-8;
double l=0,r = 10000;//浮点数范围在10000以内,有负数
while(r-l>eps){
double mid=(l+r)/2;
if(mid*mid*mid>=Math.abs(n)){
r=mid;
}else{
l=mid;
}
}
if (n >= 0)
System.out.println(String.format("%.6f", l)); // 保留 6位小数
else
System.out.println("-" + String.format("%.6f", l));
}