初等排序

本文详细介绍了四种基本排序算法:插入排序、冒泡排序、选择排序和希尔排序的工作原理及实现代码。插入排序在数据相对有序时效率较高;冒泡排序通过不断交换相邻逆序元素实现排序;选择排序每次从未排序部分选取最小值放入已排序部分;希尔排序则是改进的插入排序,通过间隔g的元素进行排序,提高效率。
摘要由CSDN通过智能技术生成
一、插入排序

插入排序算法将数组分为已排序和未排序部分:每次循环都会在已排序部分找到未排序部分开头元素的位置,将其插入。插入排序算法的时间复杂度为O(n²),但是如果数据是相对有序的,插入排序会非常高效。

  void insertSort(int arr[],int len){
    //外层循环,用于遍历未排序部分,初始时假设下标为0的部分是已排序的
        for(int i=1;i<len;i++){
           //存储未排序部分的开头元素
           int v=arr[i];
           //内层循环,用于在已排序部分插入v
            int j=i-1;
            while(j>=0&&arr[j]>v){
                //在已排序部分,将所有比v大的元素向后移动一个单位
                arr[j+1]=arr[j];
                j--;
            }
            //将v插入空位
            arr[j+1]=v;
        }
    }
    
二、冒泡排序

冒泡排序比较相邻的两个元素,从局部减少逆序数,时间复杂度为O(n²)。

    void bubbleSort(int arr[],int len){
        //每次i循环结束都会固定一个元素的位置,因此j=i+1
        for(int i=0;i<len-1;i++){
           //依次比较相邻的元素
            for(int j=i+1;j<len;j++){
                if(arr[i]>arr[j]){
                    //交换逆序的元素
                    int temp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=temp;
                }
            }
        }
    }
三、选择排序

选择排序和插入排序一样,也是将数组分为了未排序和已排序两个部分,每次从未排序部分选择一个最小的元素放到已排序部分的下一个位置。

    void selectSort(int arr[],int len){
        for(int i=0;i<len-1;i++){
            int min=i;
            for(int j=i+1;j<len;j++){
                if(arr[j]<arr[min]){
                    min=j;
                }
            }
            int temp=arr[min];
            arr[min]=arr[i];
            arr[i]=temp;
        }
    }
四、希尔排序

希尔排序是插入排序的升级版,扩大了插入排序处理相对有序的数据的优势。希尔排序每次以间隔为g的元素进行插入排序。如果g(n+1)=3g(n)+1时,希尔排序的时间复杂度为O(n^1.25)

//存储g的取值
vector<int> gArr;
void insertSort(int arr[],int len,int g){
    //假设[g,len]的元素是未排序的
    for(int i=g;i<len;i++){
        int v=arr[i];
        //假设[0,i-g]的元素是已排序的
        int j=i-g;
        while(j>=0&&arr[j]>v){
            arr[j+g]=arr[j];
            //插入数据后[0-j]的数据不再是有序,此时再以间隔为g比较新插入的元素
            j-=g;
        }
        arr[j+g]=v;
    }
}
void shellSort(int arr[],int len){
   //生成间隔g
   for(int i=1;i<=len;){
        gArr.push_back(i);
         i=i*3+1;
    }
    //逆序指定g
    for(int i=gArr.size()-1;i>=0;i--){
        insertSort(arr,len,gArr[i]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值