冒泡排序
从数组中第一个数最先,顺次遍历数组中的每个数,经由历程相邻比较交流,每一轮轮回下来找出盈余未排序数的中的最大数并”冒泡”至数列的顶端。
function bubbleSort(arr) {
for (var i = 0; i < arr.length - 1 ; i++) {
for (var j = 0; j < arr.length - i - 1 ; j++) {
if (arr[j] > arr[j+1]) { //相邻元素两两对照
let temp = arr[j+1]; //元素交流
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
console.log(bubbleSort([72,54,58,30,31,78,2,77,82,72]))
最好状况:输入数组按升序分列。 T(n) = O(n)
最差状况:输入数组按降序分列。 T(n) = O(n2)
均匀状况:T(n) = O(n2)
稳固性:稳固
挑选排序
从一切纪录中选出最小的一个数据元素与第一个位置的纪录交流;然后在剩下的纪录当中再找最小的与第二个位置的纪录交流,轮回到只剩下末了一个数据元素为止。
function selectionSort(arr) {
let minIndex,temp;
for (let i = 0; i < arr.length-1; i++) {
minIndex = i;
for (let j = i+1; j < arr.length; j++) {
if(arr[j] < arr[minIndex]) {
minIndex = j;
}
}
temp = arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
return arr;
}
console.log(selectionSort([72,54,58,30,31,78,2,77,82,72]))
最好状况:T(n) = O(n2)
最差状况:T(n) = O(n2)
均匀状况:T(n) = O(n2)
稳固性:不稳固
插进去排序
从待排序的n个纪录中的第二个纪录最先,顺次与前面的纪录比较并寻觅插进去的位置,每次外轮回完毕后,将当前的数插进去到适宜的位置。
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
let key = arr[i];
let j = i - 1;
while (j>=0 && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
return arr;
}
console.log(insertionSort([6,10,0,6,5,8,7,4,2,7]))
最好状况:输入数组按升序分列。T(n) = O(n)
最坏状况:输入数组按降序分列。T(n) = O(n2)
均匀状况:T(n) = O(n2)
稳固性:稳固
希尔排序
Shell排序法是对相邻指定距离(称为增量)的元素举行比较,并不停把增量缩小至1,完成排序。
function shellSort(arr) {
var len = arr.length,
temp,
gap = 1;
while(gap < len/5) { //动态定义距离序列
gap =gap*5+1;
}
for (gap; gap > 0; gap = Math.floor(gap/5)) {
for (var i = gap; i < len; i++) {
temp = arr[i];
for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) {
arr[j+gap] = arr[j];
}
arr[j+gap] = temp;
}
}
return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(shellSort(arr));
最好状况:T(n) = O(nlog2 n)
最坏状况:T(n) = O(nlog2 n)
均匀状况:T(n) =O(nlog n)
稳固性:不稳固
兼并排序
兼并排序是分治法(Divide and Conquer)的一个典范的运用。将已有序的子序列兼并,获得完整有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表兼并成一个有序表,称为二路兼并。
function mergeSort(arr) {
if(arr.length < 2) {
return arr;
}
let middle = Math.floor(arr.length/2);
let left = arr.slice(0,middle);
let right = arr.slice(middle);
return merge(mergeSort(left),mergeSort(right));
}
function merge(left,right) {
let res = [];
while(left.length && right.length) {
if(left[0] <= right[0]) {
res.push(left.shift());
}
else {
res.push(right.shift());
}
}
while(left.length) {
res.push(left.shift());
}
while(right.length) {
res.push(right.shift());
}
return res;
}
let arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(mergeSort(arr));
最好状况:T(n) = O(n)
最差状况:T(n) = O(nlogn)
均匀状况:T(n) = O(nlogn)
稳固性:稳固
疾速排序
1.从待排序的n个纪录中恣意拔取一个纪录(一般拔取第一个纪录)为分区规范;
2.把一切小于该排序列的纪录移动到左侧,把一切大于该排序码的纪录移动到右侧,中心放所选纪录,称之为第一趟排序;
3.然后对前后两个子序列离别反复上述历程,直到一切纪录都排好序。
要领一:
function quickSort(arr,left,right) {
let i = left;
let j = right;
let temp = 0;
if(i < j) { //待排序的元素至少有两个的状况
temp = arr[i]; //待排序的第一个元素作为基准元素
while(i != j) { //从摆布双方交替扫描,直到i = j
while(j > i && arr[j] >= temp) {
j --; //从右往左扫描,找到第一个比基准元素小的元素
}
arr[i] = arr[j]; //找到这类元素arr[j]后与arr[i]交流
while(i < j && arr[i] <= temp) {
i ++; //从左往右扫描,找到第一个比基准元素大的元素
}
arr[j] = arr[i]; //找到这类元素arr[i]后,与arr[j]交流
}
arr[i] = temp; //基准元素归位
quickSort(arr,left,i-1); //对基准元素左侧的元素举行递归排序
quickSort(arr,i+1,right); //对基准元素右侧的举行递归排序
}
return arr;
}
let arr = [5,7,1,8,4]
console.log(quickSort(arr,0,arr.length-1));
要领二:
function quickSort(arr) {
if(arr.length <= 1) {
return arr;
}
let middleIndex = Math.floor(arr.length/2);
let middle = arr.splice(middleIndex,1)[0];//拔取基准值 并从数组中删除
let left = []; //小于middle的数组
let right = []; //大于middle的数组
for (var i = 0; i < arr.length; i++) {
if(arr[i] < middle) {
left.push(arr[i]);
}
else {
right.push(arr[i]);
}
}
return quickSort(left).concat([middle],quickSort(right));
}
let arr = [5,7,1,8,4]
console.log(quickSort(arr));
最好状况:T(n) = O(nlogn)
最差状况:T(n) = O(n2)
均匀状况:T(n) = O(nlogn)
稳固性:不稳固