排序算法
基础排序算法
排序本质:减小逆序对的过程
在基础排序算法中,将待排序序列分为相对有序区与相对无序区。
每次遍历到数组末尾称为一轮。
冒泡排序(无序区-有序区, O ( n 2 ) O(n^2) O(n2),稳定,就地)
在每一轮中,逐次与下一邻项比较,每次比较将最值者置后,因此每一轮都能将无序区的1个最值放到有序区末尾,最后一轮同时将2个元素完成排序,因此最多仅需遍历 n − 1 n-1 n−1次(n:数组元素个数)
extern int a[MAX];
void sort(){for(int j=0;j<MAX-1;j++)//j:冒泡轮数=有序区元素个数for(int i=0;i<MAX-1-j;i++)//i:当前工作指针 MAX-1-j:有序区首元素(无需再进入有序区)if(a[i]>a[i+1]) swap(a[i],a[i+1]);//降序为<
}
简单选择排序(有序区-无序区, O ( n 2 ) O(n^2) O(n2),不稳定,就地)
每轮找到无序区中最值元素,并放到无序区首元素位置,无序区首元素成为有序区末尾
extern int a[MAX];
void sort(){for(int j=0;j<MAX-1;j++) {//无序区首元素下标int min=j;//默认无序区首元素为最小值for(int i=j+1;i<MAX;i++)//遍历一趟无序区获取最小值下标if(a[i]<a[min]) min=i;swap(a[j],a[min]);//交换无序区首元素与无序区最小值}
}
插入排序
直接插入排序(有序区-无序区, O ( n 2 ) O(n^2) O(n2),稳定,就地)
先默认数组首元素为有序区,其之后为无序区。顺序遍历无序区,每轮将无序区首元素,逆序遍历有序区以寻找元素插入点。
extern int a[MAX];
void sort(){for(int j=1;j<MAX;j++){//j:无序区首元素int temp=a[j],i;for(i=j-1;i>=0;i--)//逆序遍历有序区,寻找插入点if(temp<a[i]) a[i+1]=a[i];//a[i]后移else break;//找到插入点a[i+1]=temp;//a[i+1]>temp>a[i]}
}
二分插入排序( O ( n 2 ) O(n^2) O(n2),稳定,就地)
由于有序区已经是有序的,因此寻找插入点时可采用二分优化。
extern int a[MAX];
void sort(){for(int i=0;i<MAX;i++){int temp=a[i],l=0,r=i-1,m;while(l<=r){m=l+r>>1;if(t<a[m]) r=m-1;else l=m+1;}//已找到插入点lfor(int j=i-1;j>=l;j--) a[j+1]=a[j];a[l]=t;}
}