美文网首页
利用Golang实现一个类型通用的二分查找

利用Golang实现一个类型通用的二分查找

作者: MrCloudPeak | 来源:发表于2019-07-30 02:35 被阅读0次

    本文讨论的重点不是二分查找,而是如何类型通用
    众所周知,Golang不支持泛型,也不支持运算符重载。这给实现一个类型通用算法带来了一定困扰,好在还可以通过接口来实现
    如下代码中,只要实现了SortedList接口,便可使用BinarySearch函数进行二分查找。
    Golang虽然不支持泛型,但是使用接口也是可以达到类似的效果的,比如Golang自带的sort包,适合于各种类型,就是利用的这种接口机制

    package main
    
    import (
       "fmt"
    )
    /**
    用于实现二分查找的有序列表,需要实现这个接口
    其中要查找的元素,也需要放在这个list最后,因为如果这个元素不在list里,将无法与list中的元素进行比较(接口类型无法比较)
    */
    type SortedList interface {
       //返回list的长度(除去需要查找的元素)
       Len() int
       //将list[i]与需要查找的元素比较,小于返回-1,等于返回0,大于返回1
       Cmp(i int) int8
    }
    
    type Person struct {
       age int
    }
    
    type SortedPersonList []Person
    
    func (p Person) Cmp(cmp Person) int8 {
       if p.age == cmp.age {
           return 0
       } else if p.age > cmp.age {
           return 1
       } else {
           return -1
       }
    }
    
    func (s SortedPersonList) Cmp(i int) int8 {
       //将s[i]与需要查找的元素(即s最后一个元素)比较
       return s[i].Cmp(s[len(s)-1])
    }
    func (s SortedPersonList) Len() int {
       //-1是为了把最后一个需要查找的元素去掉
       return len(s) - 1
    }
    func BinarySearch(list SortedList) int {
       lower, higher := 0, list.Len()-1
       for lower <= higher {
           //防止超过int范围
           mid := lower + (higher-lower)/2
           cmp := list.Cmp(mid)
           switch cmp {
           case 0:
               return mid
           case 1:
               higher = mid - 1
           case -1:
               lower = mid + 1
           }
       }
       return -1
    }
    //这里做了一层封装,将待搜索的list,与搜索的目标作为2个参数传入
    func searchPerson(list []Person, target Person) int {
       a := append(SortedPersonList(list), target)
       return BinarySearch(a)
    }
    
    func main() {
       a := searchPerson([]Person{{12}, {13}, {14}}, Person{14})
       fmt.Println(a)
    }
    

    相关文章

      网友评论

          本文标题:利用Golang实现一个类型通用的二分查找

          本文链接:https://www.haomeiwen.com/subject/iipwrctx.html