排序一

排序一

Q: 为什么插入排序比冒泡排序更受欢迎?


经典的排序算法

排序算法 时间复杂度 是否基于比较
冒泡、插入、选择 O(n^2) Y
快排、归并 O(n*logn) Y
桶、计数、基数 O(n) N

如何分析一个排序算法?

排序算法的执行效率

  1. 最好情况、最坏情况、平均情况时间复杂度
  2. 时间复杂度的系数、常数、低阶
  3. 比较次数和交换(移动)次数

排序算法的内存消耗

  • 空间复杂度
  • def "原地排序": 特指空间复杂度为O(1)的排序算法

排序算法的稳定性

  • 稳定性的概念是说,如果待排序的序列中存在值相等的元素,经过排序后,相等元素之间原有的先后顺序不变。
  • Example: 给订单系统排序,先按下单时间排序然后再按价格排序。

冒泡排序

function bubble(arr){
	var len = arr.length;
	var flag = false;
	for(var i = 0; i<len-1;i++ ){
		for(var j = 0; j < len -1 - i; j++){
			var tmp = arr[j];
			if(arr[j]>arr[j+1]){
				arr[j] = arr[j+1];
				arr[j+1] = tmp;
				flag = true;
			}
		}
		if(!flag) break;
	}
	return arr;
}

插入排序

function insertSort(arr){
	var len = arr.length;
	for(var i = 1; i < len;++i){
		var value = arr[i];
		for(var j = i-1;j>=0;--j){
			if(arr[j] > value){
				arr[j+1] = arr[j];
			}else break;
		}
		arr[j+1] = value;
	}
	return arr;
}

选择排序

function seSort(arr){
	var len = arr.length;
	for(var i = 0; i < len -1; i++){
		var min = i;
		for(var j = i+1; j<len;j++){
			if(arr[j]<arr[min]){
				min = j;
			}
		}
		if(min!=i){
			var tmp = arr[min];
			arr[min] = arr[i];
			arr[i] = tmp;
		}
	}
	return arr;
}

三种排序算法的思想及实现

补充

  1. “有序度”: 是指数组中具有有序关系的元素队的个数。有序元素对用数学表示如下:

    有序元素对:a[i] <= a[j], 如果 i < j。
    
    
  2. “满有序度”
    $$
    n*(n-1)/2
    $$

  3. 逆序度 = 满有序度 - 有序度,【移动次数等于逆序度】

用有序度分析冒泡排序的平均时间复杂度

  • 对于包含 n 个数据的数组进行冒泡排序,平均交换次数是多少呢?最坏情况下,初始状态的有序度是 0,所以要进行 n(n-1)/2 次交换。最好情况下,初始状态的有序度是 n(n-1)/2,就不需要进行交换。我们可以取个中间值 n(n-1)/4,来表示初始有序度既不是很高也不是很低的平均情况。换句话说,平均情况下,需要n(n-1)/4次交换操作,比较操作肯定要比交换操作多,而复杂度的上限是O(n2),所以平均情况下的时间复杂度是O(n2)。

思考

若使用链表这种数据结构,以上三种排序算法相应的复杂度会怎么变化?

posted @ 2019-07-19 23:55  Mikejiawei  阅读(183)  评论(0编辑  收藏  举报