排序算法
最经典的、最常用的排序算法:冒泡排序、插入排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序。
排序算法的三种要素:
- 排序算法的执行效率
最好、最坏、平均情况时间复杂度;
时间复杂度的系数、常数、低阶;
比较次数和交换(移动)次数; - 排序算法的内存消耗
原地排序就是空间复杂度是O(1)的排序算法 - 排序算法的稳定性
待排序列的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。
1.冒泡排序
public void bubbleSort(int[] a,int n){
//n表示数据的size
if(n <= 1)
return ;
for(int i = 0;i<n;i++){
boolean flag = false;
for(int j =0;j<n-i-1 ;j++){
if(a[j]>a[j+1]){
int temp = a[j];
a[j]=a[j+1];
a[j+1]=temp;
flag =true;
}
}
if(!flag)
break;
}
}
2.插入排序
public void insertionSort(int[] a,int n){
if (n<=1)
return;
for(int i = 1;i<n;i++){
int temp = a[i];
int j = i-1;
for(;j>=0;j--){
if(a[j]>temp)
a[j+1]=a[j];
else{
break;
}
}
a[j+1]= temp;
}
}
3.选择排序
public void selectionSort(int[] a,int n){
if(n<=1)
return;
for(int i = 0;i<n;i++){
int min = i;
for(int j = i+1;j<n;j++){
if(a[j]<a[min])
min = j;
}
int temp = a[min];
a[min]= a[i];
a[i]= temp;
}
}
如果数据存储在链表中,这三种排序算法还能工作吗?如果能,那相应的时间、空间复杂度又是多少呢?
一般而言,考虑只能改变节点位置,冒泡排序相比于数组实现,比较次数一致,但交换时操作更复杂;插入排序,比较次数一致,不需要再有后移操作,找到位置后可以直接插入,但排序完毕后可能需要倒置链表;选择排序比较次数一致,交换操作同样比较麻烦。综上,时间复杂度和空间复杂度并无明显变化,若追求极致性能,冒泡排序的时间复杂度系数会变大,插入排序系数会减小,选择排序无明显变化。
4. 归并排序
int [] aux;
public void merge_sort(int[]a,int n){
aux = new int[n];
merge_sort_c(a,0,n-1);
}
public void merge_sort_c(int[]a,int lo,int hi){
if(lo>=hi)
return;
int mid = (lo