算法思路:(此算法为从大到小,可更改) 不断把数组的区间一分为二,使两端逐渐逼近与目标数近似的数,找到目标数的要插入的位置。
若插入的数是已存在需更新的,得到它原先的排序号index。先将其从数组删除,找到其区间方向(新值>旧值,则区间为[0,index];否则为[index,length(数组长度-1)]),开始进行查找。
如何通用:重点在于各种要对比大小的对象类型可能不一样,如果用>,<判断肯定是不够的,因此可以传一个委托进来,进行大小判断。传入两个参数(A,B)若A>B,则返回true ,反之则为false,若都不是A=B。
具体实现:
1 /// <summary> 2 /// 通用的降序插入算法 3 /// </summary> 4 /// <param name="sortList">插入目标链表</param> 5 /// <param name="obj">插入对象</param> 6 /// <param name="CompareFun">比较方式</param> 7 /// <param name="index">若已经存在要变值,为原对象的index</param> 8 public static void DivideInsert<T>(ref List<T> sortList,T obj,Func<T,T,bool> CompareFun,int index=-1) 9 { 10 11 if(index!=-1) 12 { 13 sortList.RemoveAt(index); 14 } 15 16 int count=sortList.Count; 17 if (count==0) 18 { 19 sortList.Add(obj); 20 return; 21 } 22 int middle,lowidx=0,highidx=count-1; 23 int dir=0; 24 if (index-1>=0) 25 { 26 if (CompareFun(obj,sortList[index-1])) 27 { 28 highidx=index-1; 29 }else 30 { 31 lowidx=index-1; 32 } 33 } 34 35 36 while(true) 37 { 38 middle=(lowidx+highidx)/2; 39 if (CompareFun(obj,sortList[middle])) 40 { 41 dir=0; 42 highidx=middle-1; 43 if(highidx<0) 44 { 45 break; 46 } 47 if(CompareFun(sortList[highidx],obj)) 48 { 49 break; 50 } 51 }else if (CompareFun(sortList[middle],obj)) 52 { 53 dir=1; 54 lowidx=middle+1; 55 if(lowidx>count-1) 56 { 57 break; 58 } 59 if(CompareFun(obj,sortList[lowidx])) 60 { 61 break; 62 } 63 } 64 else 65 { 66 dir=0; 67 middle=middle+1; 68 break; 69 } 70 } 71 sortList.Insert(middle+dir,obj); 72 }