首页 > 编程语言 >基础算法(1)

基础算法(1)

时间:2023-03-05 23:23:23浏览次数:36  
标签:right 递归 int 基础 mid while 算法 left

快速排序(O(NlogN))

思路:确定分界点(序列里随机一个数都可以):左边界、右边界、中值调整范围;递归处理左、右两段

核心:每次j指针落在i指针前面位置时,将q[i]、q[j]进行swap操作(先分两边,再递归左右)

y总讲解的图示:

代码模板:

#include <iostream>
using namespace std;

// 快速排序 
const int N = 1e6+10;

int n,q[N]; // 规模 开辟空间大小 

void quick_sort(int q[], int left, int right)
{
    if (left >= right) return;   //判断边界 
    
    int x=q[left+right >> 1]; //x是判定条件 
    int i=left-1, j=right+1 ; 
    while(i<j) //每次移动并交换 
    {
        do i++; while( q[i]<x); //对比目标,希望将i移到x右边
        do j--; while( q[j]>x); //对比目标,希望将j移到x左边
        if (i<j) swap(q[i], q[j]);    //出现问题,那就交换
    }    
    
    quick_sort(q, left, j);  //递归左半部分 
    quick_sort(q, j+1, right);//递归右半部分 
}

int main() {
    
    scanf("%d", &n);
    
    for(int i=0; i<n ; i++)
        scanf("%d", &q[i]);
    
    quick_sort(q, 0, n-1);
    
    for(int i=0; i<n; i++)
        printf("%d ", q[i]);
    
    return 0;
}

 

 

归并排序(O(NlogN))

思路:确定分界点(中值);递归排序左右边;将有序数组合并成有序数组(归并);

核心:分界点为中心点,也是双指针算法i、j(先递归左右,再分左右)

 

代码模板:

#include <iostream>
using namespace std;

// 归并排序 
const int N = 1e6+10;
int n,q[N]; // 规模 开辟空间大小 

// 图示 l_____mid______r
//        l_____mid
//         mid_____r

void merge_sort(int q[], int left, int right)
{
    if (left >= right) return; 
    
    int mid = left+right >> 1 ;  
    merge_sort(q, left, mid);  //递归左半部分 
    merge_sort(q, mid+1, right);//递归右半部分 
    
    int k=0, i=left, j=mid+1;
    while( i<=mid && j<=right)
        if (q[i]<=q[j]) newarray[k++]=q[i++]; //上 > 下,上面的放到新数组
        else newarray[k++]=q[j++];    //否则下面的放到新数组 
    
    while( i<=mid) newarray[k++]=q[i++];//剩余没排序完的直接加入新数组 
    while( j<=mid) newarray[k++]=q[j++];
    
    for (i=left, j=0; i<=r; i++,j++)
        q[i] = newarray[j];        //把新数组copy到原数组里面 
}

int main() {
    
    scanf("%d", &n);
    
    for(int i=0; i<n ; i++)
        scanf("%d", &q[i]);
    
    merge_sort(q, 0, n-1);
    
    for(int i=0; i<n; i++)
        printf("%d ", q[i]);
    
    return 0;
}

二分

整数二分:设定中值;左、右边界点与中值比较;

(1)mid = (left + right + 1)/ 2  ; true后面是l=mid,此时必须+1,防止当left=right-1时,程序发生死循环

(2)mid = (left + right)/ 2        ;

思路:在一个区间内部,每次选择一个答案所在的区间进行处理,每次都要保证区间内有答案。当区间长度为1时,区间内的数一定是答案。

图示:

模板代码:

#include <iostream>
using namespace std;
const int N = 100010 ;
int n, q[N];  
// 二分查找 有序数列中某数的始末坐标
// 1 1 2 2 3 3 4 中 3的输出为 4 5 

int main() {
    
    cin<<n<<m ; 
    
    for(int i=0; i<n; i++ ) cin>>q[i]; 
    
    while(m--)
    {
        int x; cin>>x; 
        int left=0, rigth=n-1; 
        
        while(left<right)
        {
            int mid=left+right>>1;
            if(q[mid] >= x) r=mid;
            else l=mid+1;
        }
        
        if (q[left] != x ) cout<<"-1 -1"<<endl;//没找到 
        else
        {
            cout<<left<<' '; 
            
            int left = 0, right = n-1; 
            while(l<r)
            {
                int mid = left+right+1 >> 1 ;
                if (q[mid] <= x) l=mid; 
                else r=mid-1 ; 
            }
            cout<<left<<endl;
        }
    }
    
    return 0;
}

 

浮点数二分:本质与整数二分相同,不需要处理边界,相对来说更简单

模板代码

#include <iostream>
using namespace std;
const int N = 100010 ;
int n, q[N];  
// 二分查找 有序数列中某数的始末坐标
// 1 1 2 2 3 3 4 中 3的输出为 4 5 

int main() {
    
    double l, r; 
    double x; 
    cin >> x;
    
    while(r-l > 1e-8) //浮点数切忌 == 
    {
        double mid = (l+r)/2 ; 
        if ( mid*mid >= x ) r=mid ;
        else l = mid ; 
    } 
    
    printf("%1f\n", l);
    return 0;
}

 

标签:right,递归,int,基础,mid,while,算法,left
From: https://www.cnblogs.com/zundicai/p/17182166.html

相关文章

  • go项目 -- 即时通信系统V0.1 基础server构建
    跟着b站上刘丹冰Aceld大佬开始做go项目创建server结构体,要有server的Ip和Port两个变量typeServerstruct{ Ipstring Portint}创建一个server的接口func......
  • 计算机基础_网络协议2.TCP、HTTP、HTTPS
    三次握手和四次挥手详细原理,为什么要使用这种机制?当进行第一次握手,网络不好可能会堵塞,所以连接的请求并没有到达服务器端;但是tcp连接有超时重传的机制,所以再一次发送请求,......
  • salesforce零基础学习(一百二十六) Picklist Value Set 优缺点和使用探讨
    本篇参考:https://help.salesforce.com/s/articleView?id=sf.fields_creating_global_picklists.htm&type=5当我们创建Picklist字段时,比如很多表很多字段都会用到同样的p......
  • 数字电子技术基础系统方法笔记第一章
    1.1数字和模拟信号及系统模拟量具有连续的数值,数字量具有离散的数值。自然加中大多数可以测量的对象都是模拟量。example:模拟量:温度,湿度,压力,速度。数字量:计算机储存......
  • 计算机基础_网络协议1.协议
    理解什么是协议?互联网的实现,分为好几层。每一层都是为了完成一种功能。为了实现这些功能,就需要大家都遵守共同的规则。大家都遵守的规则,就叫做"协议"了解TCP/IP网络协议......
  • Java基础随笔(2)static静态详解
    1packagecom.chapter;23classBowl{4Bowl(intmarker){5System.out.println("Bowl+("+marker+")");6}78voidf1(int......
  • 【基数排序算法详解】Java/Go/Python/JS/C不同语言实现
    说明基数排序(RadixSort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的......
  • Redis基础篇
    1、简单介绍一下Redis优点和缺点?优点:1、本质上是一个Key-Value类型的内存数据库,很像memcached2、整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据......
  • NOI / 1.7编程基础之字符串 12:加密的病历单
    描述小英是药学专业大三的学生,暑假期间获得了去医院药房实习的机会。在药房实习期间,小英扎实的专业基础获得了医生的一致好评,得知小英在计算概论中取得过好成绩后,主任又......
  • 1.7编程基础之字符串
    12:加密的病历单1.描述小英是药学专业大三的学生,暑假期间获得了去医院药房实习的机会。在药房实习期间,小英扎实的专业基础获得了医生的一致好评,得知小英在计算概论中取得......