// 从第一个开始一个一个向后比对、交换
// 改进了的冒泡排序
function sort (arr) {
let len = arr.length
,mark;
for (let i = 0; i < len - 1; i++) {
mark = 0;
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
mark = 1;
[arr[j], arr[j+1]] = [arr[j+1], arr[j]];
}
}
if (!mark) {
break
}
}
return arr
}
选择排序
// 从i(令他最小),开始寻找包含i的最小的数,i++(循环前面步骤)
function sort (arr) {
let len = arr.length
,minIndex; //选择的最小值得index
for (let i = 0; i < len - 1; i++) {
minIndex = i;
for (let j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j
}
}
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
}
return arr;
}
希尔排序
// 先分为若干子序(通过间隔, 间隔逐渐缩小为1),再分别进行插入排序
function sort (arr) {
let grap = 1
,len = arr.length
,cur
,j;
while(grap<len / 3) {
grap = grap*3 +1
}
for (grap; grap > 0; grap = Math.floor(grap / 3)) {
for (let i = grap; i < len; i++) {
cur = arr[i];
for (j = i - grap; j >= 0 && arr[j] > cur; j -= grap) {
arr[j + grap] = arr[j];
}
arr[j + grap] = cur;
console.log(arr)
}
}
return arr
}
插入排序
// 从i=1 开始,默认i=0是有序,和前面序列比较找到合适位置插入
function sort (arr) {
let len = arr.length
,preindex
,cur;
for (let i = 1; i < len; i++) {
preindex = i - 1;
cur = arr[i];
while(arr[preindex]>cur && preindex>=0) {
arr[preindex + 1] = arr[preindex];
preindex--;
}
arr[preindex+1] = cur
console.log(arr)
}
return arr
}
归并排序
// 建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。先将其划分为若干最小块,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序 小 =》 大
function mergeSort (arr) {
let len = arr.length;
if (len < 2) {
return arr
}
let midle = Math.ceil(len / 2)
,left = arr.slice(0, midle)
,right = arr.slice(midle);
return merge(mergeSort(left), mergeSort(right))
}
function merge (left, right) {
let _arr = [];
while(left.length>0 && right.length>0) {
if (left[0] <= right[0]) {
_arr.push(left.shift());
} else {
_arr.push(right.shift());
}
}
if (left.length > 0) {
_arr = _arr.concat(left)
}
if (right.length > 0) {
_arr = _arr.concat(right);
}
console.log(_arr)
return _arr;
}
快速排序
// 建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。先将其划分为若干最小块,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序 小 =》 大
function mergeSort (arr) {
let len = arr.length;
if (len < 2) {
return arr
}
let midle = Math.ceil(len / 2)
,left = arr.slice(0, midle)
,right = arr.slice(midle);
return merge(mergeSort(left), mergeSort(right))
}
function merge (left, right) {
let _arr = [];
while(left.length>0 && right.length>0) {
if (left[0] <= right[0]) {
_arr.push(left.shift());
} else {
_arr.push(right.shift());
}
}
if (left.length > 0) {
_arr = _arr.concat(left)
}
if (right.length > 0) {
_arr = _arr.concat(right);
}
console.log(_arr)
return _arr;
}
堆排序
function heapSort (arr) {
let len = arr.length;
// 根据传入的i节点的位置调整一 i 为根节点的子树
function heapify (arr, i) {
let lChildIdx = 2 * i + 1 // 左孩子
,rChildIdx = 2 * i + 2 // 右孩子
,maxIdx = i; // 此时设父节点为最大
if (lChildIdx<len && arr[lChildIdx]>arr[maxIdx]) {
maxIdx = lChildIdx;
}
if (rChildIdx<len && arr[rChildIdx]>arr[maxIdx]) {
maxIdx = rChildIdx;
}
if (maxIdx !== i) {
// 即 当前,某个子节点的值大于父节点,此时标记这个节点是父节点,更换现在父节点的值与实际父节点的值,
[arr[maxIdx], arr[i]] = [arr[i], arr[maxIdx]];
heapify(arr, maxIdx);
}
}
// 构建大顶堆(升序), 二叉树非叶节点比叶节点少一个 Math.floor(len/2-1)
// 从第一个叶节点开始,保证后面的顺序。
for(let i = Math.floor(len / 2); i >= 0; i--){
heapify(arr,i);
}
// 调整大顶堆,并排序
for (let i = len-1; i >= 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
len --; // 其中调整的是
heapify(arr, 0);
}
return arr
}
计数排序
function countingSort(arr) {
let len = arr.length
,max = arr[0]
,countArr = [];
// 寻找最大和最小 的index
for (let i = 1; i < len; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
// 得到相应的大小
countArr.length = max + 1;
countArr.fill(0);
// 技术开始
for (let i = 0; i < len; i++) {
countArr[arr[i]]++;
}
// 还原
for (let i = 0, j = 0, len = countArr.length; i < len; i++) {
for (let k = 0; k < countArr[i]; k++) {
arr[j] = i;
j++;
}
}
return arr
}
桶排序
// 插入排序
function insertSort (arr) {
let len = arr.length
,preindex
,cur;
for (let i = 1; i < len; i++) {
preindex = i - 1;
cur = arr[i];
while(arr[preindex]>cur && preindex>=0) {
arr[preindex + 1] = arr[preindex];
preindex--;
}
arr[preindex+1] = cur
}
console.log(arr)
return arr
}
// 桶排序,一个桶相当于这个数组中的数的一个区间,不同范围的数在不同的桶,然后不同的桶内再排序,再对桶排序
function bucketSort (arr, len = arr.length) {
const DEFAULT_BUCKET_SIZE = 5; // 桶大小,决定了这个桶最大数和最小数的最大的可能的差为 多少
let min = arr[0]
,max = arr[0]
,bucketSize = DEFAULT_BUCKET_SIZE //
,bucketCount
,bucketArr = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i]; // 输入数据的最小值
} else if (arr[i] > max) {
max = arr[i]; // 输入数据的最大值
}
}
// 桶和桶的数组初始化
bucketCount = Math.floor((max - min) / bucketSize) + 1
for (let i = 0; i < bucketCount; i++) {
bucketArr[i]=[];
}
// 利用映射函数将数据分配到各个桶中
for (let i = 0; i < arr.length; i++) {
bucketArr[Math.floor((arr[i] - min) / bucketSize)].push(arr[i]);
}
arr = []; // 清空arr
for (let i = 0; i < bucketArr.length; i++) {
insertSort(bucketArr[i]); // 对每个桶进行排序,这里使用了插入排序
for (let j = 0; j < bucketArr[i].length; j++) {
arr.push(bucketArr[i][j]);
}
}
return arr;
}
基数排序
function radixSort(arr, maxDigit) {
let mod = 10
,dev = 1
,counter = []
,index; // 用于更新arr
for (let i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
counter = [];
for(let j = 0; j < arr.length; j++) {
let bucket = Math.floor((arr[j] % mod) / dev);
if(!counter[bucket]) {
counter[bucket] = [];
}
counter[bucket].push(arr[j]);
}
index = 0;
for(let j = 0; j < counter.length; j++) {
// 遍历这一列统一基数的数
if(counter[j]) {
for (let i = 0, len = counter[j].length; i < len; i++) {
arr[index++] = counter[j][i]
}
}
}
}
return arr;
}
冒泡排序// 从第一个开始一个一个向后比对、交换// 改进了的冒泡排序function sort (arr) { let len = arr.length ,mark; for (let i = 0; i &lt; len - 1; i++) { mark = 0; for (let j = 0; j &lt; len - 1 - i; j++) { ...