C++十大常用排序算法

C++排序几张排序算法实现

图形化展示每种排序过程,可参考如下网站 

https://visualgo.net/zh/sorting

冒泡排序、选择排序、插入排序

https://www.bilibili.com/video/BV1dx411S74x/?spm_id_from=333.788.recommend_more_video.0

 

冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

  • 基本思想: 冒泡排序,类似于水中冒泡,较大的数沉下去,较小的数慢慢冒起来,假设从小到大,即为较大的数慢慢往后排,较小的数慢慢往前排。
  • 直观表达,每一趟遍历,将一个最大的数移到序列末尾
#include<bits/stdc++.h>

void bubbleSort(int arr[],int n){
    for(int i=0;i<n-1;i++){
        for(int j=0;j<n-1;j++){
            if(arr[j]>arr[j+1]){
                int temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
}

int main(){
    int a[100],n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    bubbleSort(a,n);
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
}

 

选择排序

#include<bits/stdc++.h>

void selectSort(int arr[],int n){
    for(int i=0;i<n-1;i++){
        int x=i;
        for(int j=i+1;j<=n;j++){
            if(arr[j]<arr[x]){
                x=j;
            }
        }
        int temp=arr[i];
        arr[i]=arr[x];
        arr[x]=temp;
    }
}
int main(){
    int a[100],n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    selectSort(a,n);
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
}

 

插入排序

 

#include<bits/stdc++.h>

void insertSort(int arr[],int n){
    for(int i=1;i<n;i++){
        int temp=arr[i];
        int j=i-1;
        while(j>=0&&temp<arr[j]){
            arr[j+1]=arr[j];
            j--;
        }
        arr[j+1] = temp;
    }
}

int main(){
    int a[100],n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    insertSort(a,n);
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
}

 

希尔排序

https://www.bilibili.com/video/BV1rE411g7rW?spm_id_from=333.337.search-card.all.click

https://www.bilibili.com/video/BV1BK4y1478X?spm_id_from=333.337.search-card.all.click

#include<bits/stdc++.h>
using namespace std;

void show(int a[],int length){
    for(int i=1;i<=length;i++)
        cout<<a[i]<<' ';
}

void shellSort(int a[],int length){
    /*
    for(int gap=length/2;gap>0;gap/=2){
        for(int i=gap+1;i<length;i++){
            int t=a[i];
            int j=i-gap;
            while(j>=1 && a[j]>t){
                a[j+gap]=a[j];
                j-=gap;
            }
            a[j+gap]=t;
        }
    }
    */
    //初始增量从length/2开始 每一趟之后除以2 
    for(int gap=length/2;gap>0;gap/=2){
        //每一趟使用插入排序 
        for(int i=gap+1;i<=length;i++){//i从gap+1开始 插入排序从第2个数开始插入到前面 
            int j=i-gap;//前面一个数 
            //j>=1 无法再往前插 
            //a[j]>a[j+gap] 前面比后面大 交换 
            /*
                3 6  插入4 
                a[j]>a[j+gap] 6>4  变成 3 4 6 j-=gap
                a[j]>a[j+gap] 3<4  while退出循环  
            */
            while(j>=1 && a[j]>a[j+gap]){
                swap(a[j],a[j+gap]);//数组根据下标交换 
                j-=gap;//是否还可以往前面插入 
            }
        }
    } 
}

int main(){
    int a[11]={0, 100, 93, 79, 71, 65, 55, 53, 21, 9,42};
    int n=10;
    /*
    for(int i=1;i<=10;i++)
        cin>>a[i];
    */
    shellSort(a,n);
    
    show(a,n);
    return 0;
}

 

快速排序

#include<bits/stdc++.h>
using namespace std;
void quickSort(int arr[],int l,int r){
    int i=l,j=r,mid=arr[l];
//    mid=arr[l+rand()%(r-l+1)];
    while(i<=j){
        while(arr[i]<mid) i++;
        while(arr[j]>mid) j--;
        if(i<=j){
            swap(arr[i],arr[j]);
            i++;
            j--;
        }
    }
    if(l<j) quickSort(arr,l,j);
    if(i<r) quickSort(arr,i,r);
}

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

 

 

归并排序

#include<bits/stdc++.h>
using namespace std;
int a[1001],b[1001];

void merge(int arr1[],int l,int mid,int r,int arr2[]){
    int i=l,j=mid+1,k=l;
    while(i<=mid && j<=r){//左右两部分追一比较,记录小的到临时数组 
        if(arr1[i]<arr1[j]){
            arr2[k++] = arr1[i++];
        }else {
            arr2[k++] = arr1[j++];
        }
    }
    //两边数据可能出现不平衡,上面while循环结束可能出现一边元素没放入临时数组情况 
    //左边没放完按顺序放,到此已经拍好序了
    //递归到最后,要么1个元素,要么2个元素,肯定上面while循环已排序或就一个元素加入 
    while(i<=mid){ 
        arr2[k++] = arr1[i++];
    }
    //右边没放完按顺序放,到此已经拍好序了
    while(j<=r){ 
        arr2[k++] = arr1[j++];    
    }
    for(i=l;i<=r;i++){
        arr1[i] = arr2[i];
    }
    cout<<endl;
}

void mergeSort(int arr1[],int l,int r,int arr2[]){
    //基本情况
    if(l==r) return;
    //原问题分解
    int mid=l+(r-l)/2;
    //解决子问题
    mergeSort(arr1,l,mid,arr2);
    mergeSort(arr1,mid+1,r,arr2);
    //合并子问题 
    merge(arr1,l,mid,r,arr2);
}

int main(){
    int a[100],n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    mergeSort(a,0,n-1,b);
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
}

 

堆排序

https://www.bilibili.com/video/BV1fp4y1D7cj/?spm_id_from=333.788

#include<bits/stdc++.h>
using namespace std;

void show(int a[],int length){
    for(int i=0;i<length;i++)
        cout<<a[i]<<' ';
}

/**
 * @brief 交换变量值
 *
 * @param a 第一个数字
 * @param b 第二个数字
 */
void swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

/**
 * 维护堆的性质 数组下标维护二叉树 
 * @param arr 存储堆的数组
 * @param len 数组长度
 * @param i 待维护节点的下标
 */
void heapify(int arr[], int len, int i){
    int largest = i;//largest默认赋值父节点下标 
    int lson = i * 2 + 1;//左孩子 
    int rson = i * 2 + 2;//右孩子 
    //largest<左孩子  largest=lson 且不出界 
    if (lson < len && arr[largest] < arr[lson])
        largest = lson;
    //larest<右孩子 largest=rson 且不出界
    if (rson < len && arr[largest] < arr[rson])
        largest = rson;
    if (largest != i){//largest 被修改 说明有左孩子或者右孩子比父节点大 
        swap(&arr[largest], &arr[i]);//父节点的值和左孩子或者右孩子交换 
        heapify(arr, len, largest);//递归 通过largest 左孩子或者右孩子进行heapify 
    }
}

// 堆排序入口
void heap_sort(int arr[], int len){
    int i;
    /*
     建堆 从最后一个元素建堆 下标为len-1 子节点对应其父节点为(i-1)/2 
     len-1的父节点 (i-1)/2=(len-1-1)/2=len/2-1 
     */ 
    for (i = len / 2 - 1; i >= 0; i--) 
        heapify(arr, len, i);

    /*
     排序 大顶堆 取出a[0] 放入最后  把n-1放入a[0]
     a[0]变化 需要重新维护堆的性质 进行heapify 
    */ 
     
    for (i = len - 1; i > 0; i--){//从n-1开始 排序 每次把最大的移动到最后 
        swap(&arr[i], &arr[0]);//把arr[0]移到最后一个 最大的移动最后 
        heapify(arr, i, 0);//heapify 维护堆的性质 
    }
}

int main(){
    int a[10]={100, 93, 79, 71, 65, 55, 53, 21, 9,42};
    int n=10;
    heap_sort(a,n); 
    show(a,n);
    return 0;
}

 

 

桶排序

#include<bits/stdc++.h>
using namespace std;

void show(int a[],int length){
    for(int i=1;i<=length;i++)
        cout<<a[i]<<' ';
}

void quickSort(int arr[],int l,int r){
    int i=l,j=r,mid=arr[l];
//    mid=arr[l+rand()%(r-l+1)];
    while(i<=j){
        while(arr[i]<mid) i++;
        while(arr[j]>mid) j--;
        if(i<=j){
            swap(arr[i],arr[j]);
            i++;
            j--;
        }
    }
    if(l<j) quickSort(arr,l,j);
    if(i<r) quickSort(arr,i,r);
}

void buckingSort(int a[],int length){
    int bucket[11][11]={0};
    for(int i=1;i<=length;i++){
        int index=a[i]/10;//分桶规则 去除末尾分桶 
        bucket[index][0]++;//此桶存放数++ 
        bucket[index][bucket[index][0]]=a[i];//相同桶放入对应列 
    }
    for(int i=0;i<=10;i++){//每一个桶使用快排排序 
        quickSort(bucket[i],1,bucket[i][0]);
    }
    int i=1;
    for(int j=0;j<=10;j++){//按桶下标从小到大输出 
        for(int k=1;k<=bucket[j][0];k++){//每桶已经排好序 按列从小到大输出 
            a[i++]=bucket[j][k];
        }
    }
} 

int main(){
    int a[11]={0, 100, 93, 79, 71, 65, 55, 53, 21, 9,42};
    int n=10;
    /*
    for(int i=1;i<=10;i++)
        cin>>a[i];
    */
//    quickSort(a,1,10);
    buckingSort(a,n);
    
    show(a,n);
    return 0;
}

 

 计数排序

#include<bits/stdc++.h>
using namespace std;

void show(int a[],int length){
    for(int i=1;i<=length;i++)
        cout<<a[i]<<' ';
}
/*
计数排序
100 93 79 71 65 55 53 21 9 42
temp[9]=1
temp[21]=1
temp[42]=1
temp[53]=1
temp[55]=1
temp[65]=1
temp[71]=1
temp[79]=1
temp[93]=1
temp[100]=1
其他temp为0 
*/ 
void countingSort(int a[],int length){
    int temp[101]={0};
    for(int i=1;i<=length;i++){
        temp[a[i]]++;//把a[i]作为下标 值累加进temp数字 
    }
    int k=1;
    for(int i=1;i<=100;i++){// 1-100循环遍历 temp[i]的值 9 23 42 ... 
        for(int j=0;j<temp[i];j++){//此数出现过几次temp[i]为几 0-8都无法进入循环 
            a[k++]=i;//按排序复原a数组 a[1]=9 a[2]=23 a[3]=42
        }
    }
}

int main(){
    int a[11]={0, 100, 93, 79, 71, 65, 55, 53, 21, 9,42};
    int n=10;
    /*
    for(int i=1;i<=10;i++)
        cin>>a[i];
    */
    countingSort(a,n);
    
    show(a,n);
    return 0;
}

 

 基数排序

#include<bits/stdc++.h>
using namespace std;

void show(int a[],int length){
    for(int i=1;i<=length;i++)
        cout<<a[i]<<' ';
}

void radixSort(int a[],int length){
    for(int tail=1;tail<=100;tail *=10){//从低位到高位循环取位权
        //10行11列 每行存储0-9 10个数
        //列 0列 存储 此数字有几个数 后面1-11存储 当前位取出数字对应的数 
        int radix[10][11]={0}; 
        for(int i=1;i<=length;i++){//循环数组中每个数 
            int index=a[i]/tail%10;//取当前位对应数字 
            radix[index][0]++;//当前数字个数 个数累加并存储radix[x][0] 
            radix[index][radix[index][0]]=a[i];//当前数字对应数存储 
        }
        int i=1;
        for(int j=0;j<10;j++){//从0开始完成一次当前数字排序 
            for(int k=1;k<=radix[j][0];k++){//radix[j][0] 当前个位(十位...)数字j对应数有几个 
                a[i++]=radix[j][k];//按本位从小到大放入a[i] 
            }
        }
    }
}
/*
100 93 79 71 65 55 53 21 9 42
71 21 42 93 53 65 55 79 9 100 个位 
9 100 21 42 53 55 65 71 79 93 十位 
9 21 42 53 55 65 71 79 93 100 百位 
*/
int main(){
    int a[11]={0, 100, 93, 79, 71, 65, 55, 53, 21, 9,42};
    int n=10;
    /*
    for(int i=1;i<=10;i++)
        cin>>a[i];
    */
    radixSort(a,n);
    
    show(a,n);
    return 0;
}

 

c++ sort

 

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[100],n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
}

 

posted @ 2020-11-01 15:16  new-code  阅读(906)  评论(0编辑  收藏  举报