多种排序算法代码小记(插入/冒泡/选择/快速/归并/更新中...)

【已有无序数组a[n],n个元素,采用不同的排序算法对齐进行升序排序】 

一、直接插入排序: 

【思路】:将数组分为有序与无序两部分,初始:【第1位是有序序列,剩下的为无序序列】,将无序数组的第一个插入到有序数组中的合适位置,有序数组扩展一位,以此迭代,直至无序数组完

【具体做法】:从第二位开始,与之前有序数组逐一比较,若比前面的数字还小则交换位置,直至不能交换说明前面比它还小,则找到最终位置

int main(){
    for(int i=1;i<n;i++){
        int p=i;
        while(a[p]<a[p-1] && p>=1){
            swap(a[p],a[p-1]);
            p--;
        }
    }
}

 

 

二、简单选择排序:

【思路】:将数组分为有序与无序两部分,从无序数组中选择最小的一个,将它放到有序数组的最后一个

【具体做法】:从1~n找出最小的放到第1位,从2~n找出最小的放在第2位,以此类推,直至n-1为被确定

int main(){
    for(int i=0;i<n-1;i++){
        int minn = 0x3f3f3f3f;
        int index = i;
        for(int j=i;j<n;j++){
            if(a[j]<minn){
                minn = a[j];
                index = j;
            }
        }
        swap(a[i],a[index]);
    }
}

 

三、快速排序:

【思路】:每次从待排序数组中拿出一枢轴(可设为序列第1位),确定枢轴的位置,使得数轴左边的比它小,右边的比它大,在递归排序枢轴左区间与右区间,直至该区间只有一位数

【具体做法】:双指针的做法,设定两个指针在区间的最左和最右,并交替向中间移动。右区间需要比枢轴大,所以右指针所指若比枢轴大则继续移动,直至该值小于枢轴,则与左指针(此时枢轴位置)交换;左区间需要比枢轴小,所以左指针所指若比枢轴小则继续移动,直至该值大于枢轴,则与右指针(此时枢轴位置)交换,最终确定枢轴位置

void Qsort(int a[],int left,int right){
    if(left>=right) return; 
    int l = left;
    int r = right;
    while(l<r){
        while(a[r]>=a[l] && l<r){
            r--;
        }
        swap(a[r],a[l]);
        while(a[l]<=a[r] && l<r){
            l++;
        }
        swap(a[r],a[l]);
    }
    Qsort(a,left,l-1);
    Qsort(a,l+1,right);
}
int main(){
    Qsort(a,0,n-1);
}

 

四、归并排序

【思路】:采用分支思想,先分后置

1、分:从中间切割该序列,分为左右区间,左右区间继续切割,直至区间只有1位数值

2、治:将小序列进行归并,注意是【有序归并】,而不是简单连接

【具体做法】:

1、分:递归切割,如mergeSort所示,直至区间只有一个值

2、治:需申请一中间数组,比较两个小序列,各有其起始指针,比较其值大小,小的放入中间数组,再见指针右移,重新比较,以此类推,直至其中一序列全被放入数组中,再将另一序列剩下部分全丢进去,注意通过中间数组【更新原数组】

void merge(int *a,int l,int r,int p,int q,int *tmp){
    int left = l;
    int right = q;
    int cnt=0;
    while(l<=r && p<=q){
        if(a[l]<a[p]){
            tmp[cnt++]=a[l++];
        }else{
            tmp[cnt++]=a[p++];
        }
    }
    while(l<=r){
        tmp[cnt++] = a[l++];
    }
    while(p<=q){
        tmp[cnt++] = a[p++];
    }
    cnt=0;
    while(left<=right){
        a[left++] = tmp[cnt++];
    }
}
void mergeSort(int *a,int l,int r,int *tmp){
    if(l!=r){
        int m = (l+r)/2;
        mergeSort(a,l,m,tmp);
        mergeSort(a,m+1,r,tmp);
        merge(a,l,m,m+1,r,tmp);
    }
}
int main(){
    mergeSort(a,0,n-1,tmp);
    for(int i=0;i<n;i++){
        cout<<a[i]<<" ";
    }
}

 

五、冒泡排序

【思路】:将序列分为有序序列和无序序列两部分,有序序列位于后半部分,初始为空,每次将无序序列中最大的一个值上升到最后,成为有序序列最前面的一个,每次最大的值都向上(后)走,故称为冒泡。

【具体操作】:无需序列两两相比,大的那个放在后面,故可实现大的数值往上冒泡。

int main(){
    int p=1;  // 记录有序序列长度
    while(p<n){
        for(int i=0;i<n-p;i++){
            if(a[i]>a[i+1]){
                swap(a[i],a[i+1]);
            }
        }         
        p++;
    }
}

 

六、折半插入排序,待更新...

 

七、堆排序,待更新...

 

​​​​​​​八、结构体排序,待更新...

 

​​​​​​​九、时空复杂度的比较,待更新...

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值