Go语言数据结构和算法(二十八)插值搜索算法

10 阅读2分钟

插值搜素是对实例二分搜索的改进.其中排序数组中的值是均匀分布的.二分搜索总是对中间元素进行检查.插值搜索可能会根据正在搜索的键的值去查找不同的位置.如果键的值更接近最后一个元素.则插值搜索很可能会向末端一侧开始搜索.

1.步骤:

1.1:从列表中间开始搜索数据.

1.2:如果匹配.则返回元素索引.然后退出.

1.3:如果不匹配则预测位置.

1.4:使用预测公式划分列表并找到新的中间点.

1.5:如果数据大于中间值.则在更高的子列表中搜索.

1.6:如果数据小于中间值.则在较低的子列表中搜索.

1.7:重复以上步骤直到匹配.

2.使用场景:

有序和均匀分布的数据:

插值搜索算法在搜索均匀分布的有效数据集中的元素时很有效.因为插值公式依赖于此属性进行准确的预测.

近似匹配:

插值搜搜算法在搜素近似匹配时很有用.因为它会在数据集中找到最接近的目标元素.

3.实现:

3.1方法:

package data

func InterpolationSearch(array []int, key int) int {
	min, max := array[0], array[len(array)-1]
	low, high := 0, len(array)-1
	for {
		if key < min {
			return low
		}
		if key > max {
			return high + 1
		}

		//预测位置.
		var guess int
		if high == low {
			guess = high
		} else {
			size := high - low
			offset := int(float64(size-1) * (float64(key-min) / float64(max-min)))
			guess = low + offset
		}
		if array[guess] == key {
			//如果预测值出现多次.
			for guess > 0 && array[guess-1] == key {
				guess--
			}
			return guess
		}
		if array[guess] > key {
			high = guess - 1
			max = array[high]
		} else {
			low = guess + 1
			min = array[low]
		}
	}
}

3.2main方法:

func main() {
	array := []int{1, 6, 8, 22, 23, 33, 55, 66, 99}
	search := data.InterpolationSearch(array, 33)
	fmt.Println(search)
}

4.实战:

给定一个有序的整数数组和一个目标值.使用插值搜索算法确定目标值是否存在.如果存在则返回索引.

4.1方法:

func InterpolationSearch2(array []int, n, target int) int {
	if n == 0 {
		return -1
	}
	low := 0
	high := n - 1
	for array[high] != array[low] && target >= array[low] && target <= array[high] {
		//预估中间值.
		mid := low + ((target - array[low]) * (high - low) / (array[high] - array[low]))
		//找到目标值.
		if target == array[mid] {
			return mid
		} else if target < array[mid] {
			high = mid - 1
		} else {
			low = mid + 1
		}
	}
	if target == array[low] {
		return low
	} else {
		return -1
	}
}

4.2main方法:

func main() {
	array := []int{2, 5, 6, 8, 9, 10}
	target := 5
	n := len(array)
	index := data.InterpolationSearch2(array, n, target)
	if index == -1 {
		fmt.Println("没有找到元素.")
	} else {
		fmt.Println("元素索引为", index)
	}
}

山也青水也秀.情也深意也重.

如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路