zoukankan      html  css  js  c++  java
  • sort.js

    JavaScript to achieve the ten common sorting algorithm library

    1
    ; 2 (function (global, factory) { 3 // 兼容amd和cmd的写法 4 // 基本的新式是 cmd ? cmd : amd ? amd : global || window 5 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 6 typeof define === 'function' && define.amd ? define(factory) : 7 (global.PAS = factory()); 8 })(this, (function () { 9 // 判断是否数组 10 function isArray(arr) { 11 return typeof Array.isArray === 'function' ? 12 Array.isArray(arr) : 13 Object.prototype.toString.call(arr) === '[object Array]'; 14 } 15 16 // 交换两个元素 17 function swap(v1, v2, context) { 18 [context[v1], context[v2]] = [context[v2], context[v1]]; 19 return void 0; 20 } 21 22 // 冒泡排序 23 function bubble(arr) { 24 let len = arr.length; 25 for (let i = 0; i < len; i++) { 26 for (let j = 0; j < len - 1 - i; j++) { 27 if (arr[j] > arr[j + 1]) { 28 swap(j, j + 1, arr) 29 } 30 } 31 } 32 return arr; 33 } 34 35 // 插入排序 36 function insert(arr) { 37 let len = arr.length; 38 let pIndex, current; // 前一个元素的索引,当前元素的值 39 for (let i = 1; i < len; i++) { 40 pIndex = i - 1; 41 current = arr[i]; 42 43 // 依次把当前元素和前面的元素进行比较 44 while (pIndex >= 0 && arr[pIndex] > current) { 45 // 比当前的元素大,向后移一位 46 arr[pIndex + 1] = arr[pIndex]; 47 pIndex--; 48 } 49 // 插入当前元素到合适的位置 50 arr[pIndex + 1] = current; 51 } 52 return arr; 53 } 54 55 // 快速排序 -- 这个方法不改变原数组 56 function quick(arr) { 57 let len = arr.length; 58 59 if (len < 2) { 60 return arr; 61 } 62 63 let middleIndex = Math.floor(len / 2); // 中间元素的索引值 64 let baseValue = arr.splice(middleIndex, 1); // 基准值 65 66 let left = []; // 保存小于基准值元素 67 let right = []; // 保存大于或等于基准值元素 68 69 for (let i = 0; i < arr.length; i++) { 70 if (arr[i] < baseValue) { 71 left.push(arr[i]); 72 } else { 73 right.push(arr[i]); 74 } 75 } 76 return quick(left).concat(baseValue, quick(right)); 77 } 78 79 // 选择排序 80 function selection(arr) { 81 let len = arr.length; 82 let minIndex = 0; // 用于保存最小值的索引 83 84 for (let i = 0; i < len - 1; i++) { 85 minIndex = i; 86 // 遍历后面的元素和当前认为的最小值进行比较 87 for (let j = i + 1; j < len; j++) { 88 if (arr[minIndex] > arr[j]) { 89 // 比认为的最小值小 交换索引 90 minIndex = j; 91 } 92 } 93 // 找到最小值和当前值交换 94 if (minIndex !== i) { 95 swap(minIndex, i, arr); 96 } 97 } 98 return arr; 99 } 100 101 // 归并排序 102 function merge(arr) { 103 let len = arr.length; 104 if (len < 2) { 105 return arr; 106 } 107 let middleIndex = Math.floor(len / 2); // 获取中间元素的索引 108 let left = arr.slice(0, middleIndex); // 获取左半部分的元素 109 let right = arr.slice(middleIndex); // 获取右半部分的元素 110 111 let merges = function (left, right) { 112 // 保存结果的数组 113 let result = []; 114 115 while (left.length && right.length) { 116 if (left[0] < right[0]) { 117 result.push(left.shift()) 118 } else { 119 result.push(right.shift()) 120 } 121 } 122 123 // 如果左半边还有元素 124 while (left.length) { 125 result.push(left.shift()); 126 } 127 128 // 如果右半边还有元素 129 while (right.length) { 130 result.push(right.shift()); 131 } 132 133 return result; 134 } 135 136 return merges(merge(left), merge(right)); 137 } 138 139 // 希尔排序 140 function shell(arr) { 141 let len = arr.length, 142 temp, 143 gap = 1; 144 145 while (gap < len / 3) { 146 gap = gap * 3 + 1; 147 } 148 149 for (gap; gap > 0; gap = Math.floor(gap / 3)) { 150 for (let i = gap; i < len; i++) { 151 temp = arr[i]; 152 for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) { 153 arr[j + gap] = arr[j]; 154 } 155 arr[j + gap] = temp; 156 } 157 } 158 return arr; 159 } 160 161 // 堆排序 162 function heap(arr) { 163 let len = arr.length; 164 165 let heapify = function ( 166 arr // 待排序的数组 167 , x // 元素的下标 168 , len // 数组的长度 169 ) { 170 let l = 2 * x + 1; 171 let r = 2 * x + 2; 172 let largest = x; 173 174 if (l < len && arr[l] > arr[largest]) { 175 largest = l; 176 } 177 178 if (r < len && arr[r] > arr[largest]) { 179 largest = r; 180 } 181 182 if (largest !== x) { 183 swap(x, largest, arr); 184 heapify(arr, largest, len); 185 } 186 } 187 188 for (let i = Math.floor(len / 2); i >= 0; i--) { 189 heapify(arr, i, len); 190 } 191 192 for (let i = len - 1; i >= 1; i--) { 193 swap(0, i, arr); 194 heapify(arr, 0, --len); 195 } 196 return arr; 197 } 198 199 // 基数排序 200 function radix(arr) { 201 const SIZE = 10; 202 let len = arr.length; 203 let buckets = []; 204 let max = Math.max.apply(null, arr); // 数组中的最大值 205 let maxLength = String(max).length; // 最大数字的长度 206 207 // 进行循环将桶中的数组填充成数组 208 for (let i = 0; i < SIZE; i++) { 209 buckets[i] = []; 210 } 211 212 // 进行循环--对数据进行操作--放桶的行为 213 for (let i = 0; i < maxLength; i++) { 214 // 第二轮循环是将数据按照个位数进行分类 215 for (let j = 0; j < len; j++) { 216 let value = String(arr[j]); 217 // 判断长度--进行分类 218 if (value.length >= i + 1) { 219 let num = Number(value[value.length - 1 - i]); // 依次的从右到左获取各个数字 220 //放入对应的桶中 221 buckets[num].push(arr[j]); 222 } else { 223 // 长度不满足的时候,就放在第一个桶中 224 buckets[0].push(arr[i]); 225 } 226 } 227 // 将原数组清空 228 arr.length = 0; 229 230 //这次循环是依次取出上面分类好的数组存放到原数组中 231 for (let j = 0; j < SIZE; j++) { 232 // 获取各个桶的长度 233 let l = buckets[j].length; 234 // 循环取出数据 235 for (let k = 0; k < l; k++) { 236 arr.push(buckets[j][k]); 237 } 238 // 将对应的桶清空,方便下次存放数据 239 buckets[j] = []; 240 } 241 } 242 return arr; 243 } 244 245 // 桶排序 -- 不改变原数组 246 function bucket(arr, size = 5) { 247 let len = arr.length; 248 if (len < 2) { 249 return arr; 250 } 251 252 // 获取最大值和最小值 253 const max = Math.max.apply(null, arr); 254 const min = Math.min.apply(null, arr); 255 256 // 计算出桶的数量 size是截距 257 const bucketCount = Math.floor((max - min) / size) + 1; 258 // 根据桶的个数创建指定长度的数组 259 const buckets = new Array(bucketCount); 260 // 将每个桶塞到大桶里面去 261 for (let i = 0; i < bucketCount; i++) { 262 buckets[i] = []; 263 } 264 // 利用映射函数将数据分配到各个桶里面去 265 for (let i = 0; i < arr.length; i++) { 266 // 逢size进1 267 let index = Math.floor((arr[i] - min) / size); 268 buckets[index].push(arr[i]); 269 } 270 //对每个桶中的数据进行排序--借助于快速排序算法 271 for (let i = 0; i < buckets.length; i++) { 272 buckets[i] = quick(buckets[i]); 273 } 274 275 // flatten数组--有点不足就是会将原数组中的String改变为Number 276 return buckets.join(',').split(',').filter(v => v !== '').map(Number); 277 } 278 279 // 计数排序 280 function count(arr) { 281 let index = 0; 282 let len = arr.length; 283 let min = Math.min.apply(null, arr); // 最小值 284 let max = Math.max.apply(null, arr); // 最大值 285 let result = []; // 结果数组 286 287 // 向新数组中填充0 288 for (let i = min; i <= max; i++) { 289 result[i] = 0; 290 } 291 // 把各个数组中对应的元素计数加一 292 for (let i = 0; i < len; i++) { 293 result[arr[i]]++; 294 } 295 // 按照计数的元素进行排序 296 for (let i = min; i <= max; i++) { 297 while (result[i]-- > 0) { 298 arr[index++] = i; 299 } 300 } 301 return arr; 302 } 303 304 const PAS = {}; 305 306 [ 307 bubble, 308 insert, 309 quick, 310 selection, 311 merge, 312 shell, 313 heap, 314 radix, 315 bucket, 316 count 317 ].forEach(function (func) { 318 let name = func.name; 319 //增加层外包装,判断参数是不是数组 320 Object.defineProperty(PAS, name, { 321 get: function () { 322 return function (args) { 323 if (!isArray(args)) { 324 throw new Error('the arguments of PAS.' + name + ' must be Array'); 325 } 326 return func.call(null, args); 327 } 328 }, 329 configurable: true 330 }) 331 332 // 在数组的原型上添加方法 333 Object.defineProperty(Array.prototype, name, { 334 get: function () { 335 var vm = this; 336 return function () { 337 return func.call(vm, vm); 338 } 339 }, 340 configurable: true 341 }) 342 }) 343 344 return PAS; 345 }))
  • 相关阅读:
    003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程
    002 01 Android 零基础入门 01 Java基础语法 01 Java初识 02 Java简介
    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学
    001 Android Studio 首次编译执行项目过程中遇到的几个常见问题
    Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器
    Dora.Interception,为.NET Core度身打造的AOP框架 [1]:更加简练的编程体验
    监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile
    轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑
    轻量级ORM框架——第一篇:Dapper快速学习
    CF888G Xor-MST(异或生成树模板)
  • 原文地址:https://www.cnblogs.com/ys-wuhan/p/6407570.html
Copyright © 2011-2022 走看看