自己写的几个练习代码——精简精简再精简

力求在正确的前提下尽量短小。

首先是atoi,设置一个全局变量valid,输入无效置为false,有效置为true,这个代码要注意6点

1,输入指针为nullptr

2,去除首部空格

3,判断正负号

4,判断没有digit的情况

5,过滤非法字符

6,判断溢出

bool valid;
#define MAX 0x7fffffff
int atoi2(const char* in){
    valid=true;
    if(in==nullptr)return valid=false;
    while(*in==' ')in++;
    bool minus=false;
    if(*in=='-'){
        minus=true;
        in++;
    }else if(*in=='+')
        in++;
    long long result=0;
    if(*in>'9'||*in<'0')return valid=false;
    while(*in<='9'&&*in>='0'){
        result=result*10+*in++-'0';
        if(result-minus>MAX)
            return valid=false;
    }
    if(minus)
        result=-result;
    return result;
}

快排,函数体只有8行,非常简单:

void qsort(int*left,int*right){
    if(right-left<2)return;
    int*p1=left,*p2=left;
    for(;p2<right;++p2)
        if(*p2<=*(right-1))swap(*p1++,*p2);
    qsort(left,p1-1);
    qsort(p1,right);
}

归并排序,因为需要额外申请空间,有额外赋值操作,所以看上去有些不和谐:

void msort(int*left,int*right){
    if(right-left<2)return;
    int*mid=left+(right-left)/2;
    msort(left,mid);
    msort(mid,right);
    vector<int>tmp;
    int*p1=left,*p2=mid;
    while(p1!=mid||p2!=right)
        if(p1==mid)tmp.push_back(*p2++);
        else if(p2==right)tmp.push_back(*p1++);
        else if(*p1<*p2)tmp.push_back(*p1++);
        else tmp.push_back(*p2++);
    for(int t:tmp)
        *left++=t;
}

堆排,a--是为了让下标从1开始,个人习惯:

void sink(int*a,int n,int i){
    if((2*i==n&&a[2*i]>a[i])||(2*i+1<=n&&a[2*i]>a[i]&&a[2*i]>=a[2*i+1])){
        swap(a[i],a[2*i]);
        sink(a,n,2*i);
    }
    else if(2*i+1<=n&&a[2*i+1]>a[i]&&a[2*i+1]>=a[2*i]){
        swap(a[i],a[2*i+1]);
        sink(a,n,2*i+1);
    }
}
void hsort(int*a,int n){
    if(a==NULL||n<2)return;
    a--;
    for(int i=n/2;i>0;--i)sink(a,n,i);
    while(n>1){
        swap(a[1],a[n--]);
        sink(a,n,1);
    }
}
下面3个排序,其实都差不多。

选择排序:

void select(int * a, int n){
    while(n--){
        int m=0;
        for(int i=1;i<=n;++i)
            if(a[i]>a[m])m=i;
        swap(a[m],a[n]);
    }
}

冒泡排序:

void bubble(int*a,int n){
    while(n--)
        for(int i=0;i<n;++i)
        if(a[i]>a[i+1])swap(a[i],a[i+1]);
}

插入排序:

void insert(int*a,int n){
    for(int i=0;i<n;++i)
        for(int j=i-1;j>=0&&a[j]>a[j+1];--j)
            swap(a[j],a[j+1]);
}

寻找第k小的元素,其实就是快排的划分,平均时间复杂度是o(n),有空再写个五分中位法:

int getK(int*left,int*right,int k){
    if(right-left==1)return*left;
    int*p1=left,*p2=left;
    for(;p2<right;++p2)
        if(*p2<=*(right-1))swap(*p1++,*p2);
    int*mid=p1-1;
    int n=mid-left+1;
    if(n==k)return *mid;
    else if(k<n)return getK(left,mid,k);
    else return getK(p1,right,k-n);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值