插入排序定义:维护一个有序区,把元素一个个插入有序区的适当位置,直到所有元素都有序为止。
例子:定义无序数组为:[5,8,6,3,9,2,1,7],第一轮循环开始前,有序区为数组第一个元素即:[5]。开始第一轮循环:让元素8和有序区[5]的元素依次比较。
8大于有序区第一个元素5,8>5,所以元素8和元素5无须交换。
此时有序区的元素增加到两个:[5,8]
第二轮:让元素6和有序区[5,8]的元素依次比较。
6小于有序区倒序第一个元素8
6<8,所以把元素6和元素8进行交换。
6大于有序区倒序第二个元素5
6>5,所以元素6和元素5无须交换。
此时有序区的元素增加到3个:[5,6,8]
第三轮:让元素3和有序区的元素依次比较,此时的有序区为[5,6,8]
3小于有序区倒序第一个元素8
3<8,所以把元素3和元素8进行交换
3小于有序区倒序第二个元素8
3<6,所以把元素3和元素6进行交换
3小于有序区倒序第三个元素5
3<5,所以把元素3和元素5进行交换
此时有序区的元素增加到了四个[3,5,6,8]
优化:
第三轮循环,把元素用inserValue存起来,把有序区的元素从前向后逐一复制。
第1步:暂存元素3,inserValue
第2步:和前一个元素比较,由于3<8,复制元素8到它下一个位置。
第3步:和前一个元素比较,由于3<6,复制元素6到它下一个位置。
第4步:和前一个元素比较,由于3<5,复制元素5到它下一个位置。
第5步:把暂存的元素3赋值到数组的首位。
js代码:
for (var i = 0; i < arr.length; i++) {
var insertValue = arr[i];
console.log("insertValue", insertValue, i);
var j = i - 1;
//从右向左比较元素的同时,进行元素赋值
for (; j >= 0 && insertValue < arr[j]; j--) {
arr[j + 1] = arr[j];
console.log("insertValue1", arr[j], j);
}
//insertValue的值插入适当位置
arr[j + 1] = insertValue;
console.log("insertValue2", insertValue, j);
}
return arr;
}
insert_sort([5,8,6,3,9,2,1,7])
时间复杂度:插入排序要进行n-1轮,每一轮在最坏情况下的比较次数最多一直到n-1次,所以最坏时间复杂度是O(n平方)。
空间复杂度:插入排序是原地排序,并没有借助额外的存储空间,所以空间复杂度是O(1)
冒泡排序定义:在排序中按照要求从小到大排序或者从大到小排序,不断比较数组中相邻两个元素的值,较小或者较大的元素前移。
js代码:
bubbling_sort(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
bubbling_sort([5,8,6,3,9,2,1,7])
插入排序与冒泡排序的区别:
1.插入排序是从正向有序的,而冒泡排序是从逆向有序,冒泡排序是每次最后的一个值都为最大或最小
2.插入排序是将无序的元素插入有序的元素序列中,插入后仍然有序;冒泡排序是比较相邻的元素,直到序列变成有序为止