如何分析一个排序算法?
排序算法的执行效率
- 最好情况,最坏的情况,平均的情况的时间复杂度
- 时间复杂度的系数,常数和低阶
- 比较次数和交换移动次数
排序算法的内存消耗
内存消耗可以通过空间复杂度来衡量,原地排序:原地排序算法是空间复杂度为O(1)的算法。
排序算法的稳定性
待排序序列存在值相等的元素,经过排序之后,经过排序之后,相等元素之间原有的先后顺序不变,那么就称为稳定。
原理
重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
原理
- (1)比较想了的元素,第一个比第二大,就交换。
- (2)对每一个相邻的元素进行同样的操作,最后的元素应该是最大的。
- (3)针对所有的元素重复以上步骤。除了最后一个。
- (4)持续每一次对越来越少的元素重复以上步骤,直到没有任何一对数字需要比较。
思路:依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面。
- (1)第一次比较:首先比较第一和第二个数,将小数放在前面,将大数放在后面。
- (2)比较第2和第3个数,将小数 放在前面,大数放在后面。
- ......
- (3)如此继续,知道比较到最后的两个数,将小数放在前面,大数放在后面,重复步骤,直至全部排序完成
- (4)在上面一趟比较完成后,最后一个数一定是数组中最大的一个数,所以在比较第二趟的时候,最后一个数是不参加比较的。
- (5)在第二趟比较完成后,倒数第二个数也一定是数组中倒数第二大数,所以在第三趟的比较中,最后两个数是不参与比较的。
- (6)依次类推,每一趟比较次数减少依次
JavaScript实现
function bubleSort(arr){
if(!arr.length) return '请给一个数组';
if(arr.length < 2) return arr;
let len = arr.length;
for(let i = 0;i<len;i++){
let flag = false;
for(let j=0;j<len-i-1;j++){
if(arr[j]>arr[j+1]){
let tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
flag = true
}
}
if(!flag) break;
}
}
冒泡排序是原地排序空间复杂度为O(1),
为稳定排序
时间复杂度
最好的情况O(n),最坏的情况是O(n2) 平均交换次数最坏是n*(n-1)/2 平均时间复杂度为n2 有序度 数组中具有有序关系的元素的个数,完全有序的叫做满有序度
逆序度 = 满有序度-有序度
算法比较编辑
排序算法 平均时间复杂度 冒泡排序 O(n2) 选择排序 O(n2) 插入排序 O(n2) 希尔排序 O(n1.5) 快速排序 O(NlogN) 归并排序 O(NlogN) 堆排序 O(N*logN) 基数排序 O(d(n+r))