基础的排序算法(选择排序,插入排序)与希尔排序
基础(o(n * n))时间复杂度的算法:
优点
1:编码简单,易于实现,是一些简单情景首选
2:可以利用基础算法衍生出复杂的排序算法
选择排序
主要是每一次找最小即可,每次从后一位找出最小的再交换位置即可
核心代码
#include<stdio.h>
selectSort(int arr[],int n){
for(int i = 0 ; i < n ; i++){
int minIndex = i;
for(int j = i + 1 ; j < n ; j++){
if(arr[j] < arr[minIndex]){
minIndex = j;
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
int main(){
int arr[7] = {5,2,3,9,7,6,1};
selectSort(arr,7);
for(int i = 0 ; i < 7 ; i++)
printf("%d ",arr[i]);
return 0;
}
插入排序,特殊的(o(n * n))的排序算法,因为插入排序的排序的特殊性,对于较为有序的数列,插入排序的时间复杂度非常之小
插入排序的核心代码
#include<stdio.h>
void InsertionSort(int arr[] , int n){
for(int i = 1 ; i < n ; i++){
int e = arr[i];
int j;
for(j = i ; j > 0 ; j--){
if(arr[j - 1] > e){ //e不变,作为判断在判断移动的数
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
}
}
int main(){
int arr[7] = {5,2,3,9,7,6,1};
InsertionSort(arr,7);
for(int i = 0 ; i < 7 ; i++)
printf("%d ",arr[i]);
return 0;
}
插入排序算法的优化,每一次进行swap交换非常耗费时间
所以,我们可以用一个辅助的数,来记录下,先单个移动就可以了
核心代码
#include<stdio.h>
void InsertionSort(int arr[] , int n){
for(int i = 1 ; i < n ; i++){
int e = arr[i];
int j;
for(j = i ; j > 0 && arr[j - 1] > e; j--){
arr[j] = arr[j - 1];
}
arr[j] = e;
}
}
int main(){
int arr[7] = {5,2,3,9,7,6,1};
InsertionSort(arr,7);
for(int i = 0 ; i < 7 ; i++)
printf("%d ",arr[i]);
return 0;
}
插入排序对于那种近乎有序的数组,有非常快的速度,但对于选择排序,每一次遍历数组,耗时十分巨大
因为它的特点,一般会与其他算法配合作为子过程
当然了,我们熟悉的冒泡排序,如果想要减少其的时间复杂度,我们可以运用插入排序优化的方法,不用每次有要使用Swap将大大减少它的时间复杂度
希尔排序
它是一个(o(3/2n))时间复杂度的排序算法,先将整个待排元素分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列基本有序,最后运用插入排序,可以使希尔排序在时间效率上比前两种方法上有较大的提高
希尔排序的核心代码
#include<stdio.h>
//希尔排序是分布的,对于不熟内进行插入排序
void ShellSort(int arr[] , int n){
int i , j , gap;
for(gap = n / 2 ; gap > 0 ; gap /= 2){
for(i = 0 ; i < gap ; i++){
for(j = i + gap ; j < n ; j += gap){
int temp = arr[j];
int k = j - gap;
while(k >= 0 && arr[k] > temp){
arr[k + gap] = arr[k];
k -= gap;
}
arr[k + gap] = temp;
}
}
}
}
int main(){
int arr[7] = {5,2,3,9,7,6,1};
ShellSort(arr,7);
for(int i = 0 ; i < 7 ; i++)
printf("%d ",arr[i]);
return 0;
}
希尔排序的优化
#include<stdio.h>
//希尔排序是分布的,对于不熟内进行插入排序
void ShellSort(int arr[] , int n){
int i,j,gap;
for(gap = n / 2 ; gap > 0 ; gap /= 2){
for(j = gap ; j < n ; j++){ //从数组gap个元素开始
if(arr[j] < j - gap){
int temp = arr[j];
int k = j - gap;
while(k >= 0 && arr[k] > temp){
arr[k + gap] = arr[k];
k -= gap;
}
arr[k + gap] = temp;
}
}
}
}
int main(){
int arr[7] = {5,2,3,9,7,6,1};
ShellSort(arr,7);
for(int i = 0 ; i < 7 ; i++)
printf("%d ",arr[i]);
return 0;
}
希尔排序的优化
#include<stdio.h>
//希尔排序是分布的,对于不熟内进行插入排序
void ShellSort(int arr[] , int n){
int i ,j,gap;
for(gap = n / 2 ; gap > 0 ; gap /= 2){
for(i = gap ; i < n ; i++){
for(j = i - gap ; j >= 0 && arr[j] > arr[j + gap] ; j -= gap){
int temp = arr[j + gap];
arr[j + gap] = arr[j];
arr[j] = temp;
}
}
}
}
int main(){
int arr[7] = {5,2,3,9,7,6,1};
ShellSort(arr,7);
for(int i = 0 ; i < 7 ; i++)
printf("%d ",arr[i]);
return 0;
}
希尔排序是在步数中进行排序的,而不是前后,当步数为1时最后一次插入排序,就可以解决问题了