zoukankan      html  css  js  c++  java
  • JavaScript中的二分法插入算法

    算法主体部分

    var OnlineUser = {
                //list  : 待查找的数组
                //key   : 待插入的值
                //order : 数组的顺序 1:从小到大 0:从大到小
                //start : 开始查找的起始下标位置
                //end   : 开始查找的结束下标位置
                //例:    
                //var arr1 = [17,15,15,14,14,13,13,8,8,7,7,6,5,4,3];
                //var key = 8;
                //var index = OnlineUser.GetPosIndex(arr1, key,0, arr1.length, 0);
                GetPosIndex:function(list,key,order,start,end)
                {
                    var index = -1;
                    var halfIndex = Math.abs(parseInt((end+start)/2));
                    
                    if(list[halfIndex] == key) //在中位
                    {
                        index = halfIndex; 
                    }
                    else if(list[halfIndex] < key && key < list[start])//在左半
                    {
                        index = OnlineUser.GetPosIndex(list, key, order, start, halfIndex); 
                    }
                    else if(list[end] < key && key < list[halfIndex])//在右半
                    {
                        halfIndex ++ ;
                        index = OnlineUser.GetPosIndex(list, key, order, halfIndex, end); 
                    }
                    else if(list[start] <= key && list[halfIndex] < key) //在左边
                    {
                        index = start; 
                    }
                    else if(list[end] >= key && list[halfIndex] > key) //在右边
                    {
                        index = end + 1;
                    }
                    else //一个值都没有
                    {
                        index = 0;
                    }
                    return index;
                },
                Sort:function(array){  
                    return array.sort(function(a, b){  
                        return b - a;  
                    });  
                },
                GetInsIndex:function(list,key)
                {
                    var index = 0;
                    //list = this.Sort(list);
                    for(var k=0;k<list.length;k++)
                    {
                        if(list[k] <= key)
                        {
                            index = k;
                            break;
                        }                
                        else if(list[k] > key)
                            index = k+1;                
                        else if(list[k] < key)
                            break;
                    }
                    return index;
                }
            }

    完整的程序和测试页面

    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    
        </head>
        <body>
            <div id ="result"></div>
        </body>
        <script lang="javascript">
            var OnlineUser = {
                //list  : 待查找的数组
                //key   : 待插入的值
                //order : 数组的顺序 1:从小到大 0:从大到小
                //start : 开始查找的起始下标位置
                //end   : 开始查找的结束下标位置
                //例:    
                //var arr1 = [17,15,15,14,14,13,13,8,8,7,7,6,5,4,3];
                //var key = 8;
                //var index = OnlineUser.GetPosIndex(arr1, key,0, arr1.length, 0);
                GetPosIndex:function(list,key,order,start,end)
                {
                    var index = -1;
                    var halfIndex = Math.abs(parseInt((end+start)/2));
                    
                    if(list[halfIndex] == key) //在中位
                    {
                        index = halfIndex; 
                    }
                    else if(list[halfIndex] < key && key < list[start])//在左半
                    {
                        index = OnlineUser.GetPosIndex(list, key, order, start, halfIndex); 
                    }
                    else if(list[end] < key && key < list[halfIndex])//在右半
                    {
                        halfIndex ++ ;
                        index = OnlineUser.GetPosIndex(list, key, order, halfIndex, end); 
                    }
                    else if(list[start] <= key && list[halfIndex] < key) //在左边
                    {
                        index = start; 
                    }
                    else if(list[end] >= key && list[halfIndex] > key) //在右边
                    {
                        index = end + 1;
                    }
                    else //一个值都没有
                    {
                        index = 0;
                    }
                    return index;
                },
                Sort:function(array){  
                    return array.sort(function(a, b){  
                        return b - a;  
                    });  
                },
                GetInsIndex:function(list,key)
                {
                    var index = 0;
                    //list = this.Sort(list);
                    for(var k=0;k<list.length;k++)
                    {
                        if(list[k] <= key)
                        {
                            index = k;
                            break;
                        }                
                        else if(list[k] > key)
                            index = k+1;                
                        else if(list[k] < key)
                            break;
                    }
                    return index;
                }
            }
        
            var result = document.getElementById("result");       
            //测试用例,子数组第一个为从小到大顺序,第二个从大到小的顺序
            var testArray = [
                [[],[]],
                [[1],[1]],
                [[1,2,3,4,5],[17,15,14,13]],
                [[11,12,13,14,15],[7,6,5,4,3,2,1]],
                [[1,2,3,4,5,7,7,7,8,8,9,9,10],[17,15,15,14,14,13,13,8,8,7,7,6,5,4,3]],
                [[1000003,1000003,1000003,1000003,1000003,11000269],[11000269,1000003,1000003,1000003,1000003,1000003]]
            ];
            
            //期望值
            var expectArray = [
                [[0],[0]],
                [[1],[0]],
                [[5],[4]],
                [[0],[0]],
                [[10],[7]],
                [[5],[1]]
            ];
            
            //各用例要查找的值
            var testKey = [
                [8],
                [8],
                [8],
                [8],
                [8],
                [1000003]            
            ];
            
            var start =0;//开始查找的起始下标位置
            var end =0;  //开始查找的结束下标位置
            var index = 0; //待插入的位置
            
            
            for(var i=0;i<testArray.length;i++) //组数
            {
                result.innerHTML += "<hr />";
                for(var j=0;j<testArray[i].length;j++) //组单元
                {
                    if(j==1) //大到小
                    {                    
                        start = 0;
                        end = testArray[i][j].length - 1; 
                        index = OnlineUser.GetPosIndex(testArray[i][j], testKey[i][0],1, start, end);
                        result.innerHTML += "<br />small -> big: ["+testArray[i][j].toString()+"],  key:"+testKey[i]+",  index:" + index +", expect:"+expectArray[i][j]+ ((index == expectArray[i][j])?"":",<font color='red'>NotEq</font>");
                    }
                    else //从小到大
                    {
                        continue;
                        start =  testArray[i][j].length - 1;
                        end = 0;                    
                        index = OnlineUser.GetPosIndex(testArray[i][j], testKey[i][0],0, start, end);
                        result.innerHTML += "<br />big <- small: ["+testArray[i][j].toString()+"],  key:"+testKey[i]+",  index:" + index+", expect:"+expectArray[i][j]+ ((index == expectArray[i][j])?"":",<font color='red'>NotEq</font>");                   
                    } 
                }
            }
            /* */
            
            //构造测试数据
            var bufferArray = [];
            var newArray = [10002107,10002107,10000003,10002057,10000037,10000037,10000007,10000007,10000007,10000007,10000007,10000007,10000007,10000007,10002067,10000005,10000005,10000005,10000007,10000007,10000005,10000005,10000005,10000005,10000005,10000005,10000005,10000005,10000005,10000005,10000005,10000005];
            newArray.reverse();
            for(var n = 0;n<10000;n++)
            {
                newArray[n] = parseInt(10000000 + Math.random() * 1000000);
            }         
            var key = parseInt(10000000 + Math.random() * 1000000); 
            
            //IE弹出"是否停止运行此脚本"脚本超时时间设置 
            //1. 打开注册表HKEY_CURRENT_USERSoftwareMicrosoftInternetExplorerStyles,如果 Styles 键不存在,创建调用 Styles 的一个新的项
            //2. 创建新的 DWORD 值在此项下称为"MaxScriptStatements"并将值设置为所需的脚本语句数,如100000000
    
            // ***************** 以下数据准确性测试 *********************   
            //系统法排序
            var bArray = OnlineUser.Sort(newArray); 
            
            //二分法插入
            for(var m=0; m < newArray.length;m++)
            {
                var index = OnlineUser.GetPosIndex(bufferArray, newArray[m], 1,0, bufferArray.length-1);
                //var index = OnlineUser.GetPosIndex(bufferArray, newArray[m], 0, bufferArray.length,0);
                bufferArray.splice(index, 0, newArray[m]);
            }
            
            //结果打印
            var a = bufferArray.toString();
            var b = bArray .toString();
            result.innerHTML += "<br />Rnd:" + newArray.toString();
            result.innerHTML += "<br />Dic:" + a;
            result.innerHTML += "<br />Sys:" + b;
            result.innerHTML += "<br /> Eq:" + (a == b);
    
            
            
            
            // ***************** 以下性能测试 *********************
            //将数据分为5段,做采样
            var keyArr = [];
            for(var ki=0;ki<5;ki++)
            {
                keyArr.push(newArray.length * ki * 0.2);
            }        
            
            var cnt = 1000;
            var idx =0 ;        
            var dateStart,dateEnd,timeSpan; 
            
            //遍历方法插入
            result.innerHTML += "<br />"+keyArr.toString();
            result.innerHTML += "<br />GetInsIndex: ckey key idx cnt t(ms)";
            for(var ckey=0;ckey<keyArr.length;ckey++)
            {
                dateStart = new Date(); //@@@TEST         
                for(var x=0;x<cnt;x++ )
                {  
                    idx = OnlineUser.GetInsIndex(bArray, bArray[keyArr[ckey]]+1);        
                }
                dateEnd = new Date();t = dateEnd.getTime() - dateStart.getTime();
                result.innerHTML +="<br />"+ckey+" "+keyArr[ckey] + " "+idx+" "+cnt+" "+t;
            }
            
            cnt = 10000;
            //二分法插入
            result.innerHTML += "<br />GetPosIndex: ckey key idx cnt t(ms)";
            for(var ckey=0;ckey<keyArr.length;ckey++)
            {
                dateStart = new Date(); //@@@TEST         
                for(var x=0;x<cnt;x++ )
                {  
                    idx = OnlineUser.GetPosIndex(bArray, bArray[keyArr[ckey]]+1,1,0,bArray.length -1 );          
                }
                dateEnd = new Date();t = dateEnd.getTime() - dateStart.getTime();
                result.innerHTML +="<br />"+ckey+" "+keyArr[ckey] + " "+idx+" "+cnt+" "+t;
            } 
        </script>
    </html>
  • 相关阅读:
    如何用StatSVN统计SVN服务器某项目的代码量
    探秘JVM的底层奥秘
    SpingMVC流程图
    NioCopy文件
    我的angularjs源码学习之旅3——脏检测与数据双向绑定
    我的angularjs源码学习之旅2——依赖注入
    我的angularjs源码学习之旅1——初识angularjs
    IE兼容性问题汇总【持续更新中】
    nodejs学习笔记四——express-session
    我理解的this
  • 原文地址:https://www.cnblogs.com/janas/p/3319793.html
Copyright © 2011-2022 走看看