排序算法总结(C++)

1冒泡排序

改进1 添加sorted 表示是否已经排序

void bubbleSort(vector<int>& array) {
    int n = array.size() ;
    for (int i = 0; i < n - 1;i++){
    	int sorted = true;
        for (int j = 0; j < n - i - 1;j++){
            if(array[j]>array[j+1])
               {
                   swap(array[j], array[j + 1]);
                   sorted = false;
               }
        }
        if(sorted){
            break;
        }
    }
}

假设每趟都是有序,如果发生交换则表示无序,同时记录最后一次发生交换的下标,内层循环最大值就是它

void bubbleSort(vector<int>& array) {
    int n = array.size();
    int secondCount  = n-1;
    for (int i = 0; i < n-1;i++){
        bool sorted = true;
        int lastChangeIndex = 0;
        for (int j = 0; j <secondCount ;j++){
            if(array[j]>array[j+1]){
                swap(array[j],array[j+1]);
                sorted = false;
                lastChangeIndex = j;
            }
        }
        if(sorted){
            break;
        }
        secondCount = lastChangeIndex;
    }
}

2 选择排序

void selectionSort(vector<int>& array) {
    int n = array.size();
    for (int i = 0; i < n-1; i++)
    {
        int minIndex = i;
        for (int j = i; j < n; j++)
        {
            if (array[j] < array[minIndex]) //找到最小的数
                minIndex = j;               //将最小数的索引保存
        }
        if(i!=minIndex)
        swap(array[i], array[minIndex]);
            
    }
}

3 插入排序

void insertsort1(vector<int>& array) {
    int n = array.size();
    for (int i = 1; i < n; i++)
    {
        int cur = i;
        while(cur>0&&(array[cur]<array[cur-1])){
            swap(array[cur], array[cur - 1]);
            cur--;
        }
    }
}
  

优化一 将其中的交换改为挪动
在这里插入图片描述

void insertsort2(vector<int>& array) {
    int n = array.size();
    for (int i = 1; i < n; i++)
    {
        int cur = i;
        int value = array[i];
        while(cur>0&&(value<array[cur-1])){
            array[cur] = array[cur - 1];
            cur--;
        }
        array[cur] = value;
    }


}

优化二 在之前的算法中 我们是需要在有序序列中选择一个合适的位置进行插入 然后将之后的有序序列往后移动。在这里我们对于位置的插入可以采用二分查找的策略

int search  (vector<int>& array,int index ){
    int begin = 0;
    int end = index;
    int val = array[index];
    while(begin<end){
        int mid = (begin + end) >> 1;
        if(val<array[mid]){
            end = mid;
        }
        else{
            begin = mid + 1;
        }
    }
    return begin;
}
void insertsort3(vector<int>& array) {
    int n = array.size();
    for (int i = 1; i < n; i++)
    {
        int pos = search(array, i);
        int val = array[i];
        for (int j = i; j > pos;j--){
            array[j] = array[j - 1];
        }
        array[pos] = val;
    }
}

总结下二分查找

int search  (vector<int>& array,int val ){
    int begin = 0;
    int end = array.size();
    while(begin<end){
        int mid = (begin + end) >> 1;
        //注意此处是<= 如果和要插入的数相等的数有好几个, 是插在最右边的位置
        if(val<array[mid]){
            end = mid;
        }
        else{
            begin = mid + 1;
        }
    }
    return begin;
}
int main(){

    vector<int> v{1,2,3,4,4,4,5,6,8};
    cout<<search(v,0)<<endl; //0
    cout<<search(v,1)<<endl; //1
    cout<<search(v,4)<<endl; //6
    cout<<search(v,5)<<endl; //7
    cout<<search(v,7)<<endl; //8
    cout<<search(v,9)<<endl; //9
    cout << endl;
}
int search  (vector<int>& array,int val ){
    int begin = 0;
    int end = array.size();
    while(begin<end){
        int mid = (begin + end) >> 1;
        //注意此处是<= 如果和要插入的数相等的数有好几个, 是插在最左边的位置
        if(val<=array[mid]){
            end = mid;
        }
        else{
            begin = mid + 1;
        }
    }
    return begin;
}
int main(){

    vector<int> v{1,2,3,4,4,4,5,6,8};
    cout<<search(v,0)<<endl; //0
    cout<<search(v,1)<<endl; //0
    cout<<search(v,4)<<endl; //3
    cout<<search(v,5)<<endl; //6
    cout<<search(v,7)<<endl; //8
    cout<<search(v,9)<<endl; //9
    cout << endl;
}

找到的话输出位置,没找到输出-1

int search  (vector<int>& array,int val ){
    int begin = 0;
    int end = array.size();
    while(begin<end){
        int mid = (begin + end) >> 1;
        if(val<array[mid]){
            end = mid;
        }
        else if(val>array[mid]){
            begin = mid + 1;
        }
        else{
            return mid;
        }
    }
    return -1;
}
int main(){

    vector<int> v{1,2,3,4,4,4,5,6,8};
    cout<<search(v,0)<<endl; //-1
    cout<<search(v,1)<<endl; //0
    cout<<search(v,4)<<endl; //4
    cout<<search(v,5)<<endl; //6
    cout<<search(v,7)<<endl; //-1
    cout<<search(v,9)<<endl; //-1
    cout << endl;
}
int search  (vector<int>& array,int val ){
    int begin = 0;
    int end = array.size()-1;//改动的地方
    while(begin<=end){
        int mid = (begin + end) >> 1;
        if(val<array[mid]){
            end = mid-1;
        }
        else if(val>array[mid]){
            begin = mid + 1;
        }
        else{
            return mid;
        }
    }
    return -1;
}
int main(){

    vector<int> v{1,2,3,4,4,4,5,6,8};
    cout<<search(v,0)<<endl; //-1
    cout<<search(v,1)<<endl; //0
    cout<<search(v,4)<<endl; //4
    cout<<search(v,5)<<endl; //6
    cout<<search(v,7)<<endl; //-1
    cout<<search(v,9)<<endl; //-1
    cout << endl;
}

4快速排序

void quicksort(vector<int> &v, int left,int right) {
        if(left<right){
            int pivot = v[left];
            int low = left, high = right;
            while(low<high){
                while(low<high){
                    if(v[high]>pivot){
                        high--;
                    }else{
                        v[low++] = v[high];
                        break;
                    }
                }
                while(low<high){
                    if(v[low]<pivot){
                        low++;
                    }else{
                        v[high--] = v[low];
                        break;
                    }
                }
            }
            v[low] = pivot;
            quicksort(v, left, low - 1);
            quicksort(v, high + 1, right);
        }
}

5希尔排序

希尔排序的步长可以自己设置

void shellSort(vector<int>&a,int len)
{
    
    int step = len >> 1;//设置步长
    while(step) // while gap>=1
    {
    	//这里是插入排序
        for (int col = 0; col < step;++col){

            for (int begin = col + step; begin < len; begin += step){
                int cur = begin;
                while (cur>col&&a[cur]<a[cur-step]){
                    swap(a[cur], a[cur - step]);
                    cur -= step;
                }
            }
        }
        step = step >> 1;
    }
}

6计数排序

void countSort(vector<int>&a)
{

    int len = a.size();
    int min = a[0], max = a[0];
    for (int i = 1; i < len;i++){
        if(a[i]>max)
            max = a[i];
        if(a[i]<min)
            min = a[i];
    }
    vector<int> count(max-min+1);
    for (int i = 0; i < len;i++){
        count[a[i] - min]++;
    }
    for (int i = 1; i < count.size();i++){
        count[i] += count[i - 1];
    }
    vector<int> res(len);
    for (int i = len - 1; i >= 0;i--){
        res[--count[a[i] - min]] = a[i];
    }
    for (int i = 0; i < len;i++){
        a[i] = res[i];
    }
}

此外还有归并排序 推排序 桶排序 基数排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值