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]); } }
作者:newcode 更多资源请关注纽扣编程微信公众号
从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习