算法——各种类型对象通用的二分法插入排序

算法思路:(此算法为从大到小,可更改) 不断把数组的区间一分为二,使两端逐渐逼近与目标数近似的数,找到目标数的要插入的位置。

若插入的数是已存在需更新的,得到它原先的排序号index。先将其从数组删除,找到其区间方向(新值>旧值,则区间为[0,index];否则为[index,length(数组长度-1)]),开始进行查找。

如何通用:重点在于各种要对比大小的对象类型可能不一样,如果用>,<判断肯定是不够的,因此可以传一个委托进来,进行大小判断。传入两个参数(A,B)若A>B,则返回true ,反之则为false,若都不是A=B。

具体实现:

/// <summary>
        /// 通用的降序插入算法
        /// </summary>
        /// <param name="sortList">插入目标链表</param>
        /// <param name="obj">插入对象</param>
        /// <param name="CompareFun">比较方式</param>
        /// <param name="index">若已经存在要变值,为原对象的index</param>
           public static void  DivideInsert<T>(ref List<T> sortList,T obj,Func<T,T,bool> CompareFun,int index=-1)
           {    
               
               if(index!=-1)
               {
                   sortList.RemoveAt(index);
               }
               //数组长度 
               int count=sortList.Count;
         //中间数序号,[lowidx,highidx]区间两端序号
int middle,lowidx=0,highidx=count-1;
         //obj和在最后比较出middle数的左边还是右边,不太好理解,具体看一下算法
int dir=0;
         //需更新对象在list中的原序号
if (index!=-1) { if (CompareFun(obj,sortList[index])) { highidx=index; }else { lowidx=index; } }
         //若list为空,直接加
if (count==0) { sortList.Add(obj); return; } //循环找出obj要插入的位置序号 while(true) { middle=(lowidx+highidx)/2; if (CompareFun(obj,sortList[middle])) { dir=0; highidx=middle-1; if(highidx<0) { break; } if(CompareFun(sortList[highidx],obj)) { break; } }else if (CompareFun(sortList[middle],obj)) { dir=1; lowidx=middle+1; if(lowidx>count-1) { break; } if(CompareFun(obj,sortList[lowidx])) { break; } } else { dir=0; middle=middle+1; break; } } sortList.Insert(middle+dir,obj); }

猜你喜欢

转载自www.cnblogs.com/ninomiya/p/9091849.html