一、排序算法的作用:
二、基础排序算法:
(1)选择排序:
关键代码实现:
#define swap(a,b){\ //交换a,b
__typeof(a) __c=(a);\ //将a赋值给__c,同时,__c的类型与a的类型一样
(a)=(b);\ //将b赋值给a
(b)=__c;\ //将__c赋值给b
}
void selection_sort(int *arr,int l,int n){ //选择排序
for(int i=l;i<n-1;i++){ //从下标0开始
int ind=i; //假设下标为ind的数组元素最小
for(int j=i+1;j<n;j++){
if(arr[ind]>arr[j])ind=j; //如果有比下标ind更小的,则更新下标ind
}
swap(arr[i],arr[ind]); //将两个元素交换
}
return;
}
(2)插入排序:
关键代码实现:
#define swap(a,b){\ //交换a,b
__typeof(a) __c=(a);\
(a)=(b);\
(b)=__c;\
}
void insert_sort(int *arr,int b,int n){ //插入排序,b=0
for(int i=b+1;i<n;i++){ //待排序区从1开始
int j=i; //记录已排序区的最大下标
while(j>b&&arr[j]<arr[j-1]){ //对新插入到已排序区的元素进行排序
swap(arr[j],arr[j-1]);
j-=1;
}
}
return;
}
(3)希尔排序:
关键代码实现:
#define swap(a,b){\ //交换a,b
__typeof(a) __c=(a);\ //将__c的类型在编译时,转换为与a相同的类型并赋值
(a)=(b);\ //赋值交换
(b)=__c;\ //赋值交换
}
void insert_sort(int *arr,int b,int n,int step){ //插入排序,b为起始下标,n为最大下标
int ind=b; //记录要开始进行插入排序的点
for(int i=b+step;i<n;i+=step){ //每次对间隔为step的元素排序
if(arr[i]<arr[ind])ind=i; //记录数组下标大而数据小的元素
}
while(ind>b){
swap(arr[ind],arr[ind-step]); //交换元素
ind-=step; //每次对间隔为step的元素进行排序
}
for(int i=b+2*step;i<n;i+=step){
int j=i;
while(arr[j]<arr[j-step]){
swap(arr[j],arr[j-step]);
j-=step;
}
}
return;
}
void shell_sort(int *arr,int b,int n){
int k=2,bc=(n-b),step;
do{
step=bc/k==0?1:(bc/k);
for(int i=b,I=b+step;i<I;i++){
insert_sort(arr,i,n,step);
}
k*=2;
}while(step!=1);
return;
}
(4)快速排序:
关键代码实现:
#define swap(a,b){\
__typeof(a) __c=(a);\
(a)=(b);\
(b)=__c;\
}
void quick_sort(int *arr,int l,int r){
if(r-l<=2){
if(r-l<=1)return;
if(arr[l]>arr[l+1])swap(arr[l],arr[l+1]);
return;
}
int x=l,y=r-1,z=arr[l];
while(x<y){
while(x<y&&z<=arr[y])--y;
if(x<y)arr[x++]=arr[y];
while(x<y&&arr[x]<=z)++x;
if(x<y)arr[y]=arr[x];
}
arr[x]=z;
quick_sort(arr,l,x);
quick_sort(arr,x+1,r);
return;
}
int main(){
(5)归并排序:
关键代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define SMALL 1000000
__attribute__((constructor))
void __init_Rand__(){
srand(time(0));
}
bool check(int *arr,int l,int r){
for(int i=l+1;i<r;i++){
if(arr[i]<arr[i-1])return false;
}
return true;
}
#define swap(a,b){\
__typeof(a) __c=(a);\
(a)=(b);\
(b)=__c;\
}
#define TEST(func,arr,n){\
printf("TEST:%s",#func);\
int *temp=(int *)malloc(sizeof(int)*n);\
memcpy(temp,arr,sizeof(int)*n);\
long long b=clock();\
func(temp,0,n);\
long long e=clock();\
if(check(temp,0,n)){\
printf("\tOK");\
}else{\
printf("\tNO");\
}\
printf("\t%lldms\n",(e-b)*1000/CLOCKS_PER_SEC);\
free(temp);\
}
int *getRandData(int n){
int *arr=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
arr[i]=rand()%100+1;
}
return arr;
}
int *buff; //额外存储空间
void merge_sort(int *arr,int l,int r){ r为数组长度,l为开始位置,初始为0
if(r-l<=1)return; //如果只有一个元素,返回结果
int mid=(l+r)/2; //每次都将数组二分
merge_sort(arr,l,mid); //递归二分前半段的数组
merge_sort(arr,mid,r); //递归二分后半段的数组
int p1=l,p2=mid,k=0;//p1记录第一个数组元素下标,p2记录中间元素下标,k记录当前位置,便于排序
while(p1<mid||p2<r){ //前半段数组范围、后半段数组范围
if(p2==r||(p1<mid&&arr[p1]<=arr[p2])){
buff[k++]=arr[p1++];
}else{
buff[k++]=arr[p2++];
}
}
for(int i=l;i<r;i++)arr[i]=buff[i-l];
return;
}
int main(){
int *arr=getRandData(SMALL);
buff=(int *)malloc(sizeof(int)*SMALL);
TEST(merge_sort,arr,SMALL);
free(buff);
return 0;
}
(6)基数排序:
关键代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define K 65536
#define SMALL 1000000
__attribute__((constructor))
void __init_Rand__(){
srand(time(0));
}
#define swap(a,b){\
__typeof(a) __c=(a);\
(a)=(b);\
(b)=__c;\
}
bool check(int *arr,int l,int r){
for(int i=l+1;i<r;i++){
if(arr[i]<arr[i-1])return false;
}
return true;
}
#define TEST(func,arr,n){\
printf("TEST:%s",#func);\
int *temp=(int *)malloc(sizeof(int)*n);\
memcpy(temp,arr,sizeof(int)*n);\
long long b=clock();\
func(temp,0,n);\
long long e=clock();\
if(check(temp,0,n)){\
printf("\tOK");\
}else{\
printf("\tNO");\
}\
printf("\t%lldms\n",(e-b)*1000/CLOCKS_PER_SEC);\
free(temp);\
}
int *getRandData(int n){
int *arr=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
arr[i]=rand()%100+1;
}
return arr;
}
void radix_sort(int *arr,int l,int r){
int *cnt=(int *)malloc(sizeof(int)*K);
int *temp=(int *)malloc(sizeof(int)*r);
memset(cnt,0,sizeof(int)*K);
for(int i=0;i<r;i++)cnt[arr[i]%K]+=1;
for(int i=1;i<K;i++)cnt[i]+=cnt[i-1];
for(int i=r-1;i>=l;i--)temp[--cnt[arr[i]%K]]=arr[i];
memcpy(arr,temp,sizeof(int)*r);
memset(cnt,0,sizeof(int)*K);
for(int i=0;i<r;i++)cnt[arr[i]/K]+=1;
for(int i=1;i<K;i++)cnt[i]+=cnt[i-1];
for(int i=r-1;i>=l;i--)temp[--cnt[arr[i]/K]]=arr[i];
memcpy(arr,temp,sizeof(int)*r);
free(temp);
free(cnt);
return;
}
int main(){
int *arr=getRandData(SMALL);
TEST(radix_sort,arr,SMALL);
free(arr);
return 0;
}
文章到此结束!