之前发了一个减面算法,但是效率不怎么样。最近又在优化。为了不再进行Dictionary的重新排序(耗时最多的地方),改用OrderedDictionary进行插入删除操作,这样应该能节约不少时间。稍微了解了下,OrderedDictionary是采用红黑树的数据结构,效率应该是很不错的。那么,之前耗时最严重的重新排序变成了查找需要插入的位置。网上找了找最常见的几种查找算法,顺序查找(效率太低,淘汰),二分查找,插值查找,斐波拉契查找,二叉搜索树查找,平衡二叉树查找。。。好吧,一大堆。因为如果要用树结构,就需要重新存储数据,并定义结点,暂时放一边,先实现了二分查找和插值查找。
public static int InsertID(ref OrderedDictionary CostList,float target,int min,int max) { int mid = (min + max) >>1; if (target <= (float)CostList[0]) { return 0; } else if (target >= (float)CostList[CostList.Count-1]) { return CostList.Count - 1; } if (min > max) { return 0; } if (target == (float)CostList[mid] || (target >= (float)CostList[mid] && target <= (float)CostList[mid+1])) { return mid; } else if (target > (float)CostList[mid]) { return InsertID(ref CostList, target, mid + 1, max); } else { return InsertID(ref CostList, target, min, mid - 1); } } //插值查找 public static int InsertionSearch(ref OrderedDictionary a, float value, int low, int high) { if (value <= (float)a[0]) { return 0; } else if (value >= (float)a[high]) { return a.Count - 1; } int mid = low +(int)((value - (float)a[low]) / ((float)a[high] - (float)a[low])) * (high - low); if ((float)a[mid] == value || (value>= (float)a[mid] && value <= (float)a[mid+1])) return mid; if ((float)a[mid] > value) return InsertionSearch(ref a, value, low, mid - 1); if ((float)a[mid] < value) return InsertionSearch(ref a, value, mid + 1, high); return -1; }
果然在数据比较规律的情况下插值查找的效率比二分查找要高。但是在数据量超过10w的时候效率还是不怎么好。至于斐波拉契查找,很忧伤截止发文也没有实现出来。这里很感谢https://www.cnblogs.com/yw09041432/p/5908444.html 提供的代码,学习借鉴了。