1.插入排序
1.1直接插入排序
1.1.1算法原理
基本操作是将某个数字插入到一个有序数组中。第i趟插入排序是将数组中第i个元素插入到数组中的正确位置。未插入前数组前i-1个元素有序排列,插入后前i个元素有序排列。遍历数组完成每个元素的插入从而得到一个有序数组。插入时首先要寻找插入的位置,寻找过程中把相应元素后移。
1.1.2算法实现
void straight_insert(int* p,int array_size){
int temp=p[0];
for(int i=1;i<array_size;++i){
if(p[i]<p[i-1]){
temp=p[i];
p[i]=p[i-1];
int j=i-2;
for(;j>=0;--j){
if(p[j]>temp){
p[j+1]=p[j];
}
else{
p[j+1]=p[j];
break;
}
}
p[j+1]=temp;//注意这行语句的位置,不要写到第二个for循环里面,否则当插入位置是第一个位置时会比较麻烦
}
}
}
函数的第一个参数是待排序数组的指针,第二个参数是数组大小。
1.2希尔排序
1.2.1算法原理
希尔排序又称缩小增量排序。分析直接插入排序,其时间复杂度为O(n^2)。但若待排序数组是一个有序数组,则时间复杂度为O(n),所以若待排序数字组基本有序,则直接插入排序的效率可大大提高。同时n较小时,直接插入排序的效率也很高。希尔排序从这两方面入手对直接插入排序进行改进。他的基本思想是先将待排序数组分割成若干子数组,对子数组分别进行直接插入排序,最后进行一次整体的直接插入排序。具体来说,第一趟排序是待排序数组每5个元素进行直接插入排序,第二趟排序是待排序数组每3个元素进行一次直接插入排序,最后一趟排序则整体进行一次直接插入排序。
1.2.2算法实现
void shell_insert(int* p,int array_size,int dk){
for(int i=dk;i<array_size;++i){
int temp=p[i];
if(p[i]<p[i-dk]){
p[i]=p[i-dk];
int j=i-dk-dk;
for(j;j>=0;j=j-dk){
if(p[j]>temp){
p[j+dk]=p[j];
}
else{
p[j+dk]=p[j];
break;
}
}
p[j+dk]=temp;
}
}
}
void shell_sort(int* p,int array_size,int* all_dk,int dk_num){
for(int i=0;i<dk_num;++i)
shell_insert(p,array_size,all_dk[i]);
}
函数shell_sort中的前两个参数分别是待排序数组的指针和大小,后两个参数是增量数组和他的大小。增量数组严格递减,且最后一个元素是1。函数shell_insert是直接插入排序的变体,增量由1变成了dk。
2.快速排序
2.1冒泡排序
2.1.1算法原理
第一趟排序将最大元素放到数组末尾,第二趟排序将第二大元素放到数组倒数第二个位置,直到将最小元素放到数组第一个位置,排序完成。
2.1.2算法实现
void maopao(int* p,int array_size){
for(int i=0;i<array_size;++i){
for(int j=0;j<array_size-i-1;++j){
if(p[j]>p[j+1]){
int temp=p[j];
p[j]=p[j+1];
p[j+1]=temp;
}
}
}
}
2.2快速排序
2.2.1算法原理
根据数组第一个元素对数组进行划分,并查找出他的正确位置i。划分后数组前i-1个元素均小于第一个元素,i+1之后的元素均大于第二个元素。之后对这两部分递归调用快速排序,从而是整个数组有序。
2.2.2算法实现
int partition_array(int* p,int array_size,int low,int high){
int temp=p[low];
while(low<high){
while(low<high&&p[high]>=temp) --high;
p[low]=p[high];
while(low<high&&p[low]<=temp) ++low;
p[high]=p[low];
}
p[low]=temp;
return low;
}
void quick_sort(int* p,int array_size,int low,int high){
if(low>=high)
return;
int part=partition_array(p,array_size,low,high);
quick_sort(p,array_size,low,part-1);
quick_sort(p,array_size,part+1,high);
}
函数partition_array对待排序数组进行划分,并返回第一个元素的正确位置,即划分位置。
3.选择排序
3.1简单选择排序
3.1.1算法原理
第一趟排序:从数组第一个位置遍历,找出最小元素,并放到第一个位置。
第二趟排序:从数组第二个位置遍历,找出第二小元素,并放大第二个位置。
以此类推,直到完成数组最大元素的查找并安放到正确位置。
3.1.2算法实现
void simple_select_sort(int* p,int array_size){
for(int i=0;i<array_size;++i){
int min_num=p[i];
int min_index=i;
for(int j=i+1;j<array_size;++j){
if(p[j]<min_num){
min_num=p[j];
min_index=j;
}
}
if(min_index!=i){
p[min_index]=p[i];
p[i]=min_num;
}
}
}