排序:直接插入、直接选择、冒泡排序、快速排序
概念:稳定性
稳定排序:待排序数列中相同的值,排序之后相对的先后的位置不会发生改变的排序算法
不稳定排序:待排序数列中相同的值,排序之后相对的先后的位置可能会发生改变的排序算法
冒泡排序
//对arr进行冒泡排序 基本实现
function bubbleSort(arr) {
if (!Array.isArray(arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
//外层循环控制趟数
for (let i = 0; i < LEN - 1; i++) {
//内层循环控制第i趟的相邻元素的比较和交换
for (let j = 0; j < LEN - i - 1; j++) {
//如果前面的比后面的大,交换
if (arr[j] > arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
//冒泡排序的优化 待排序区在排序的过程中,如果已经是一个有序的数列了,就不需要再排序了
var counter = 0;
function bubbleGoodSort(arr) {
if (!Array.isArray(arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
//外层循环控制趟数
for (let i = 0; i < LEN - 1; i++) {
counter++;
//内层循环控制第i趟的相邻元素的比较和交换
var flag = false;
for (let j = 0; j < LEN - i - 1; j++) {
//如果前面的比后面的大,交换
//如果在整个内层循环中,if条件都没有成立,那么待排序区就是一个有序的数列了
if (arr[j] > arr[j+1]){
flag = true;
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
//如果flag还是false,那么就可以结束排序了
if (!flag)
return ;
}
return arr;
}
选择排序
选择排序基本原理:从无序区中找一个最小元素,和无序区的第一个元素进行比较
function selectSort(arr){
if (!Array.isArray) {
return;
}
const LEN = arr.length;
if (LEN === 0) {
return;
}
//外层循环控制趟数,长度为LEN-1
//i既为外层循环的控制变量,也作为无序区的第一个元素的索引
for (let i = 0; i < LEN - 1; i++) {
//无序区的最小元素索引
//先假设无序区的最小元素的索引是无序区的第一个元素
var minIndex = i;
//内层循环控制第i趟的最小元素的查找
for (let j = i + 1; j < LEN; j++) {
//找最小元素的过程
minIndex = arr[j] < arr[minIndex] ? j : minIndex;
/* if (arr[j] < arr[minIndex]) {
//minIndex永远保存的是最小元素的索引
minIndex = j;
} */
}
//内层循环外,最小元素和无序区的第一个元素互换
if (minIndex !== i) {
//无序区的第一个元素不是最小元素
var temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
return arr;
}
插入排序
插入排序的核心思想:将无序区的第一个元素,插入到有序区的合适的位置
function insertSort(arr){
if (!Array.isArray) {
return;
}
const LEN = arr.length;
if (LEN === 0) {
return;
}
//外层循环控制趟数,i还用来代表无序区的第一个元素的索引
for (let i = 1; i < LEN; i++) {
//备份无序区的第一个元素
var temp = arr[i];
///内层循环负责第i趟的有序区的元素的比较和移动
//j逆序取到有序区的所有的元素
for (var j = i-1; j >= 0; j--) {
if(arr[j] > temp){
//后移元素
arr[j+1] = arr[j];
}else{
break;
}
}
//将备份的数据,插入到合适的位置
arr[j+1] = temp;
}
return arr;
}
function insertSort1(arr){
if (!Array.isArray) {
return;
}
const LEN = arr.length;
if (LEN === 0) {
return;
}
//外层循环控制趟数,i还用来代表无序区的第一个元素的索引
for (let i = 1; i < LEN; i++) {
//备份无序区的第一个元素
var temp = arr[i];
///内层循环负责第i趟的有序区的元素的比较和移动
//j逆序取到有序区的所有的元素
for (var j = i-1; j >= 0 && arr[j] > temp; j--) {
arr[j+1] = arr[j];
}
//将备份的数据,插入到合适的位置
arr[j+1] = temp;
}
return arr;
}
快速排序
function quickSort(arr) {
if (!Array.isArray (arr))
return;
const LEN = arr.length;
if (LEN <= 1)//长度小于等于1,返回自身
return arr;
//删除并获得中间的值
var midValue = arr.splice (LEN >> 1, 1);
var small = [];
var big = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < midValue)
small.push (arr[i]);
else
big.push (arr[i]);
}
//对small和big进行上述的递归的操作
var smallArr = quickSort (small);
var bigArr = quickSort (big);
return smallArr.concat (midValue, bigArr);
}