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_USER\Software\Microsoft\InternetExplorer\Styles,如果 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>

 

posted @ 2013-09-13 17:35  全栈深入  阅读(1902)  评论(0编辑  收藏  举报