前言
学习工作多年,逐渐悟得一名优秀的程序员应有的态度———**优雅的解决问题**。简而言之,解决问题并不是最终解,如何求得该问题的最优解才是一名优秀程序员应该考虑的问题。360
同事对待问题的态度让我这种感觉愈发强烈。
思考
最近笔者在考虑如下一个需求:
现有一集团,内部网络划分为N多个子网(N>100),该N多个子网网段互相之间不交叉。有一批告警数据,该数据里携带了产生告警事件的设备
IPv4
地址,现笔者需要根据设备IPv4
地址,将这些告警数据按子网网段分类。
以上问题可抽象为:
问题Q:存在区间[1, 100],该区间是由[1, 10], [11, 20], [21, 30]…[91, 100]等子区间组成,现给定一个正整数N(1 <= N <= 100),求解N落在那个子区间。
注解:将N多个子网网段用区间(由计算机网络可知
IPv4
地址为32位无符号整数)的形式表现,比如子网网段10.95.12.0/24
表示的IPv4
地址范围为:10.95.12.0
~10.95.12.255
(即:0xa5f0c00
~0xaf0cff
),其他网段类推,由此可见该需求属于我们问题Q的同一类问题。
我们尝试去解决问题Q,首先比较容易想到,也是实现比较简单的便是**遍历**[1, 10], [11, 20]…[91, 100]等所有子区间,用N与子区间的左右端点作比较,确定N所在的子区间。显而易见,该方法简单明了,时间复杂度为O(n)。
子区间数目越多,遍历一次花费的代价就越大,在海量数据的处理中,这显然是不可忍受的。我们观察到子区间[1, 10], [11, 20], [21, 30]…[91, 100]是连续的,于是我们自然而然的想到了二分查找与二叉搜索树,不同的是以前我们接触的大多是单个节点的查找,现在是范围(即:子区间)的查找,由此今天的主角便登场了——线段树(又名区间树)。