Acwing基础算法课day1--基础算法

Acwing基础算法课day1--基础算法

  • 快速排序--分治(用数)
    • 思想
    • 代码
  • 归并排序--分治(数组mid)
    • 思想
    • 代码
  • 3.二分
    • 3.1整数二分
      • 思路
      • 模板
      • 3.2 浮点数二分
        • 模板

快速排序–分治(用数)

思想

1.确定分界点x:左边界/中间/右边界/随机
2.调整区间:<=x,(分界点不一定是x),>=x
3.递归处理左右两个区间

代码

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;//边界检查

    int i = l , j = r , x = q[l ];//i
    while (i < j)
    {
         while (q[i] < x) i++;
         while (q[j] > x) j++;
         if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);//此时j在i左边,此时x不能选左边界,防止死循环
}

最好使用scanf,比cin快
选左边界,用右指针递归
选右边界,用左指针递归

归并排序–分治(数组mid)

思想

1.确定分界点:mid=(left+right)/2
2.递归排序左右两个分区
3.合二为一,将两个有序的数组合并为一个:双指针算法 O(n)

代码

int tmp[];//中间数组0
void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;//边界条件

    int mid = l + r >> 1; //右移1位操作相当于除2
    merge_sort(q, l, mid);//左递归
    merge_sort(q, mid + 1, r);//右递归
    //合并,空间O(n)
    int k = 0, i = l, j = mid + 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 (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

稳定性:元素的相对位置在排序之后不变则稳定,否则不稳定
快排:不稳定,改进改为二元组排序 平均O(nlogn)
归并:稳定 O(nlogn)

3.二分

3.1整数二分

注意边界问题,会造成死循环
有单调性的题目一定可以二分
可以二分的题目不一定具有单调性

思路

mid=l+r/2

模板

bool check(int x){}

//向下取整,区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用
int binsearch1(int l,int r)
{
   while(l<r)
   {
   int mid=(l+r)/2;
   if(check(mid)) r=mid;
   else l=mid+1;
   }
   return l;
}

//向上取整,区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int binsearch2(int l,int r)
{
    while(l<r);
    {
    int mid=l+r+1>>1;
    if(check(mid)) l=mid;
    else r=mid-1;
    }
    return l;
}

l=mid mid=l+r+1>>1
二分的时候一定是有解的,一定可以将边界分出来
无解是因为题目

3.2 浮点数二分

没有边界问题,区间可以严格的对半分

模板

你可能感兴趣的:(Acwing算法,算法,数据结构)