zoukankan      html  css  js  c++  java
  • js随机数生成与排序

    'use strict';
    // 排序算法、
    
    
    
    // 生成一个指定数量的不含重复数字的随机数组
    function ranArr(n,callback) {
        var res = [];
        var tmp ;
        res = lack(res,n);
        ckRanArr(res,n,0,function (res) {
            return callback(res);
        });
    }
    
    
    // 生成一个指定范围内(正整数 a到b)的随机数
    function ranNum(a,b){
        var n = Math.abs(a - b );
        var base_n = a;
        if(a > b){ base_n = b; }
        var res = Math.floor(Math.random()*n) + base_n;
        return res;
    }
    
    // 返回去除重复项后的数组
    function quchong(arr) {    
        var arr2 = arr.slice(0);
        var arr2_len = arr2.length;
        var arr3 = [];
    
        for(var j = 0;j < arr2_len;j++){
        // 重复项不进新数组 去重
        (function (item,ind) {
            var flag = false;
            for(var k = (ind + 1);k < arr2_len; k++){
                if(item == arr2[k]){
                    flag = true;
                }
            }
            if(!flag){
                arr3.push(item);
            }
        }) (arr2[j],j);
        }    
        return arr3;
    }
    
    // 补缺失的量并检查
    function lack(arr,n) {    
        // 去重后数量少了 补上
        var arr_len = arr.length;
        if(arr_len < n){
            var lack = n - arr_len;
            for(var j = 0; j < lack;j++){
                arr.push( ranNum(0,100000000) );
            }
        }
        return arr;
    }
    
    // 递归检查函数  count:重试次数 重试次数限制与生成数量相关
    function ckRanArr(arr,n,count,callback){    
        
        var limit;
        if(n < 1000){
            limit = 10*n;
        }
        if(n >= 1000){
            limit = n;
        }
        if(count <  limit){
            count++;
            var arr2 = quchong(arr);  // 去重 
            if(arr2.length < n ){
                var arr3 = lack(arr2,n);  // 补量
                ckRanArr(arr3,n,count,callback);
            }
            else{
                return callback(arr2);
            }
        }
        else{
            return callback( quchong(arr) );
        }
    }
    
    ranArr(10,function (res) {
        console.log(res);
    });

     // 上面的递归调用会发生每个函数都是一个栈,会生成一个不断堆叠的函数栈直到最后一个栈函数return后依次退出。

    // 同步循环生成版
    function ranArr2(n){
        var arr = [];
        arr = lack(arr,n);
        var limit;
        if(n < 1000){
            limit = 10*n;
        }
        else{
            limit = n;
        }
        cl:for(var i = 0;i < limit;i++){ console.log(i);  
            var arr2 = quchong(arr);  // 去重
            if(arr2.length < n){
                arr = lack(arr2,n); // 补量
            }
            else{
                break cl;
            }
        }
        return arr;
    }

    优化性能效率版

    // 前两个版本生成指定数量不重复的随机数效率太低了,
    // 举例生成1000个 每一次去重时都需要接近1000 x 1000次的比较
    // 优化之后速度有了极大的提升
    // 生成范围 0-30000  生成20000个不重复随机数
    // ranArr2 平均需要23s(秒)左右
    // ranArr3 平均需要300ms左右  
    //在数据范围和数据量接近 重复几率大的时候1位1位排重的方式具有很高的性能
    //在数据范围和数据量差距很大 10万条 1亿    ran3平均需要5s左右 ran2需要23s左右
    // 数据范围增加100倍 10万条 ran2 21s左右
    
    function ranArr3(n) {
    
        var arr = [];
        var arr2 = [];
        if(n <= 0){
            return arr2;
        }
        arr = lack(arr,n);
        arr2.push(arr[0]);
        // console.log('第0个数:'+arr2);
        var arr_len = arr.length;
        for (var i = 1; i < arr_len; i++) {
            // console.log('第'+i+'个数:'+arr[i]); 
            arr2 = not_in_arr_item(arr[i],i,arr2 );
            // console.log('得到arr2为:['+arr2+']');
        }
        return arr2;
    }
    
    // 给定一个数组 和元素,返回一个不在数组中已有元素的元素
    function not_in_arr_item(item,ind,arr2) {
        //console.log( '每次进入: '+ 'item:' + item + '  ind:' + ind + ' [' + arr2 + ']');
    
        var flag = false;
        cl:for (var j = 0; j < ind; j++) {
            // console.log('j:'+j);
            if(item == arr2[j]){
                flag = true;
                break cl;
            }
        }
        // console.log(flag);
        if(flag){
            item = ranNum(0,100000000000); 
            //console.log('进入ran: '+item);
            return not_in_arr_item(item,ind,arr2);
        }
        if(!flag){
            arr2.push(item);
            return arr2;
        }
    }

    排序算法部分

    //                  取5次的平均时间
    // 比较  (个数)       冒泡          快速排序     插入排序
    //       100          0.354ms      0.443ms       0.294ms
    //       1000         2.94ms       2.351ms       1.89ms 1.84ms
    //       10000        158.39ms     12.15ms       56.8ms 55.3ms
    //       50000        5026ms       54ms          1286ms 1298ms
    
    // 冒泡排序
    function maopao(arr) {
        var arr1 = arr.slice(0);
        var len = arr1.length;
        for(var i = 0;i < len;i++){
            for(var j = (i+1);j<len;j++){
                if(arr1[i] > arr1[j]){
                    var tmp = arr1[i];
                    arr1[i] = arr1[j];
                    arr1[j] = tmp;
                }
            }
        }
        return arr1;
    }
    
    // console.time('maopao');
    // var maopao_arr = maopao(arr1);
    // console.timeEnd('maopao');
    // console.log(maopao_arr);
    
    // 快排 快速排序
    //1、找基准(一般是以中间项为基准)
    //2、遍历数组,小于基准的放在left,大于基准的放在right
    //3、递归
    function kuaipai(arr) {
        if(arr.length<=1){return arr;}
        var index = Math.floor(arr.length/2);
        var base_num = arr.splice(base_num,1)[0];
    
        var l = [];
        var r = [];
        var len = arr.length;
        for(var i = 0; i < len;i++){
            if(arr[i]<= base_num){
                l.push(arr[i]);
            }
            else{
                r.push(arr[i]);
            }
        }
        return kuaipai(l).concat( [base_num],kuaipai(r) );
    }
    
    
    // console.time('kuaipai');
    // var kuaipai_arr = kuaipai(arr1);
    // console.timeEnd('kuaipai');
    // console.log(kuaipai_arr);
    
    // 插入排序
    // 类似于斗地主整理牌时窝们人类所使用的算法:不断把牌抽出来,插入到已有牌中应处的位置
    // 将n个元素的数列分为已有序和无序两个部分 
    // 将该数列的第一元素视为有序数列,后面都视为无序数列
    // 将无序数列中的元素插入到有序数列的对应位置,插入前通过比大小的方式找到其在有序数列中的对应位置。
    // 找位置的时候有两种方式找,就近找可以减少比较次数
    function insertSort(arr){
        var len = arr.length;
        for (var i = 1; i < len; i++) {
            //不断和前一个数比
            if(arr[i] < arr[i-1] ){
                var el = arr[i];
    
                var ind;
                //找插入位置
                look: for(var j = 0;j<len;j++){
                    if( el < arr[j]){
                        ind = j;
                        break look;
                    }
                }
    
                // 从j开始到原插入元素部分全部后移一位
                for(var k = i;k>j;k--){
                    arr[k] = arr[k-1]
                }
                arr[ind] = el;
            }
        }
        return arr;
    }
    // console.log(arr1);
    // console.time('insertSort');
    // var insert_arr = insertSort(arr1);
    // console.timeEnd('insertSort');
    // console.log(insert_arr);
    
    function insertSort2(arr) {
        var len = arr.length;
        for (var i = 1; i < len; i++) {
            if(arr[i] < arr[i-1] ){
                var el = arr[i];
                arr[i] = arr[i-1];
    
                var j = i-1;
                while( (j >= 0) && (el < arr[j]) ){
                    arr[j+1] = arr[j];
                    j--;
                }
                arr[j] = el;
            }
        }
        return arr;
    }
    // console.log(arr1);
    console.time('insertSort2');
    var insert_arr2 = insertSort(arr1);
    console.timeEnd('insertSort2');
    // console.log(insert_arr2);

    paixu.js

    'use strict';
    // 排序算法、
    
    var arr1 = ranArr2(1000);
    //                  取5次的平均时间
    // 比较  (个数)       冒泡          快速排序     插入排序
    //       100          0.354ms      0.443ms       0.294ms
    //       1000         2.94ms       2.351ms       1.89ms 1.84ms
    //       10000        158.39ms     12.15ms       56.8ms 55.3ms
    //       50000        5026ms       54ms          1286ms 1298ms
    
    // 冒泡排序
    function maopao(arr) {
        var arr1 = arr.slice(0);
        var len = arr1.length;
        for(var i = 0;i < len;i++){
            for(var j = (i+1);j<len;j++){
                if(arr1[i] > arr1[j]){
                    var tmp = arr1[i];
                    arr1[i] = arr1[j];
                    arr1[j] = tmp;
                }
            }
        }
        return arr1;
    }
    
    // console.time('maopao');
    // var maopao_arr = maopao(arr1);
    // console.timeEnd('maopao');
    // console.log(maopao_arr);
    
    // 快排 快速排序
    //1、找基准(一般是以中间项为基准)
    //2、遍历数组,小于基准的放在left,大于基准的放在right
    //3、递归
    function kuaipai(arr) {
        if(arr.length<=1){return arr;}
        var index = Math.floor(arr.length/2);
        var base_num = arr.splice(base_num,1)[0];
    
        var l = [];
        var r = [];
        var len = arr.length;
        for(var i = 0; i < len;i++){
            if(arr[i]<= base_num){
                l.push(arr[i]);
            }
            else{
                r.push(arr[i]);
            }
        }
        return kuaipai(l).concat( [base_num],kuaipai(r) );
    }
    
    
    // console.time('kuaipai');
    // var kuaipai_arr = kuaipai(arr1);
    // console.timeEnd('kuaipai');
    // console.log(kuaipai_arr);
    
    // 插入排序
    // 类似于斗地主整理牌时窝们人类所使用的算法:不断把牌抽出来,插入到已有牌中应处的位置
    // 将n个元素的数列分为已有序和无序两个部分 
    // 将该数列的第一元素视为有序数列,后面都视为无序数列
    // 将无序数列中的元素插入到有序数列的对应位置,插入前通过比大小的方式找到其在有序数列中的对应位置。
    // 找位置的时候有两种方式找,就近找可以减少比较次数
    function insertSort(arr){
        var len = arr.length;
        for (var i = 1; i < len; i++) {
            //不断和前一个数比
            if(arr[i] < arr[i-1] ){
                var el = arr[i];
    
                var ind;
                //找插入位置
                look: for(var j = 0;j<len;j++){
                    if( el < arr[j]){
                        ind = j;
                        break look;
                    }
                }
    
                // 从j开始到原插入元素部分全部后移一位
                for(var k = i;k>j;k--){
                    arr[k] = arr[k-1]
                }
                arr[ind] = el;
            }
        }
        return arr;
    }
    // console.log(arr1);
    // console.time('insertSort');
    // var insert_arr = insertSort(arr1);
    // console.timeEnd('insertSort');
    // console.log(insert_arr);
    
    function insertSort2(arr) {
        var len = arr.length;
        for (var i = 1; i < len; i++) {
            if(arr[i] < arr[i-1] ){
                var el = arr[i];
                arr[i] = arr[i-1];
    
                var j = i-1;
                while( (j >= 0) && (el < arr[j]) ){
                    arr[j+1] = arr[j];
                    j--;
                }
                arr[j] = el;
            }
        }
        return arr;
    }
    // console.log(arr1);
    console.time('insertSort2');
    var insert_arr2 = insertSort(arr1);
    console.timeEnd('insertSort2');
    // console.log(insert_arr2);
    
    // 生成一个指定数量的不含重复数字的随机数组
    // 同步递归回调版
    function ranArr(n,callback) {
        var res = [];
        res = lack(res,n);
        ckRanArr(res,n,0,function (res) {
            return callback(res);
        });
    }
    // 同步循环生成版
    function ranArr2(n){
        var arr = [];
        arr = lack(arr,n);
        var limit;
        if(n < 1000){
            limit = 10*n;
        }
        else{
            limit = n;
        }
        cl:for(var i = 0;i < limit;i++){ //console.log(i);  
            var arr2 = quchong(arr);  // 去重
            if(arr2.length < n){
                arr = lack(arr2,n); // 补量
            }
            else{
                break cl;
            }
        }
        return arr;
    } 
    
    // 生成一个指定范围内(正整数 a到b)的随机数
    function ranNum(a,b){
        var n = Math.abs(a - b );
        var base_n = a;
        if(a > b){ base_n = b; }
        var res = Math.floor(Math.random()*n) + base_n;
        return res;
    }
    
    // 返回去除重复项后的数组
    function quchong(arr) {    
        var arr2 = arr.slice(0);
        var arr2_len = arr2.length;
        var arr3 = [];
    
        for(var j = 0;j < arr2_len;j++){
        // 重复项不进新数组 去重
        (function (item,ind) {
            var flag = false;
            for(var k = (ind + 1);k < arr2_len; k++){
                if(item == arr2[k]){
                    flag = true;
                }
            }
            if(!flag){
                arr3.push(item);
            }
        }) (arr2[j],j);
        }    
        return arr3;
    }
    
    // 补缺失的量并检查
    function lack(arr,n) {    
        // 去重后数量少了 补上
        var arr_len = arr.length;
        if(arr_len < n){
            var lack = n - arr_len;
            for(var j = 0; j < lack;j++){
                arr.push( ranNum(0,100000000) );
            }
        }
        return arr;
    }
    
    // 递归检查函数  count:重试次数 重试次数限制与生成数量相关
    function ckRanArr(arr,n,count,callback){    
        
        var limit;
        if(n < 1000){
            limit = 10*n;
        }
        if(n >= 1000){
            limit = n;
        }
        if(count <  limit){
            count++;
            var arr2 = quchong(arr);  // 去重 
            if(arr2.length < n ){
                var arr3 = lack(arr2,n);  // 补量
                ckRanArr(arr3,n,count,callback);
            }
            else{
                return callback(arr2);
            }
        }
        else{
            return callback( quchong(arr) );
        }
    }
    
    // console.time('a');
    // var tmp = ranArr2(1000);
    // console.timeEnd('a');
    // console.log( tmp );
    
    // ranArr(10,function (res) {
    //     console.log(res);
    // });
  • 相关阅读:
    托付和事件的使用
    在使用supervisord 管理tomcat时遇到的小问题
    无法安装vmware tools的解决方PLEASE WAIT! VMware Tools is currently being installed on your system. Dependin
    (转)Openlayers 2.X加载高德地图
    (转)openlayers实现在线编辑
    (转) Arcgis for js加载百度地图
    (转)Arcgis for js加载天地图
    (转) 基于Arcgis for Js的web GIS数据在线采集简介
    (转) Arcgis for js之WKT和GEOMETRY的相互转换
    (转)Arcgis for Js之Graphiclayer扩展详解
  • 原文地址:https://www.cnblogs.com/isdom/p/webclips072.html
Copyright © 2011-2022 走看看