搜索之顺序搜索二分搜索|Go主题月

343 阅读2分钟

搜索是指从元素集合中找到某个特定元素的过程。搜索过程通常返回true或false,分别表示元素是否存在。

顺序搜索(无序、有序列表)

存储于列表等集合中的数据项彼此存在线性或顺序的关系,每个数据项的位置与其他数据项相关。在Golang数组、切片中,数据项的位置就是它的下标。因为下标是有序的,所以能够顺序访问,由此可以进行顺序搜索。

顺序搜索原理:从列表的第一个元素开始,沿着默认的顺序逐个查看,直到找到目标元素或者查完列表。如果查完列表后仍没有找到目标元素,则说明目标元素不在列表中。

无序列表的顺序搜索Golang代码实现如下:

package main

import "fmt"

func unorderedSequentialSearch(numList []int, num int) bool {
	exist := false
	for _, value := range numList {
		if value == num {
			exist = true
			break
		}
	}

	return exist
}

func main() {
	numList := []int{2, 3, 1, 53, 23, 10}
	fmt.Println(unorderedSequentialSearch(numList, 33))
	// false
	fmt.Println(unorderedSequentialSearch(numList, 1))
	// true
}

假设列表中的元素按照升序排序。如果存在目标元素, 那么它出现在n个位置中任意一个位置的可能性仍然一样大,因此比较次数与在无序列表中相同。不过,如果不存在目标元素,那么搜索效率就会提高。如果碰到一个已比目标元素还大的元素,那么意味着后面所有的元素都不是目标元素,可以提前结束查找,不必搜完整个列表。

有序列表的顺序搜索Golang代码实现如下:

package main

import "fmt"

func orderedSequentialSearch(numList []int, num int) bool {
	exist := false
	for _, value := range numList {
		if value == num {
			exist = true
			break
		} else if value > num {
			break
		}
	}

	return exist
}

func main() {
	numList := []int{0, 1, 2, 3, 4, 5, 6}
	fmt.Println(unorderedSequentialSearch(numList, 33))
	// false
	fmt.Println(unorderedSequentialSearch(numList, 1))
	// true
}

有序列表优先使用二分搜索

二分搜索是从中间的元素着手。如果这个元素就是目标元素,那就立即停止搜索;如果不是,则利用列表有序的特性,排除一半的元素。如果目标元素比中间的元素大,就可以直接排除列表的左半部分和中间的元素。这是因为,如果列表包含目标元素,它必定位于右半部分。接下来,针对右半部分一分为二。从中间的元素着手,将其和目标元素比较。同理,要么直接找到目标元素,要么将右半部分一分为二,再次缩小搜索范围。

有序列表的二分搜索Golang代码实现如下:

package main

import "fmt"

func binarySearch(numList []int, num int) bool {
	first := 0
	last := len(numList) - 1
	exist := false

	for ;(first <= last) && !(exist); {
		midPoint := (first + last) / 2
		if numList[midPoint] == num {
			exist = true
		} else {
			if num < numList[midPoint] {
				last = midPoint - 1
			} else {
				first = midPoint + 1
			}
		}
	}
	return exist
}

func main() {
	numList := []int{0, 1, 2, 3, 4, 5, 6}
	fmt.Println(binarySearch(numList, 2))
	// true
	fmt.Println(binarySearch(numList, 9))
	// false
}