常用算法
>>>1. 顺序查找, 也叫线性查找, 它从第一个记录开始, 挨个进行对比, 是最基本的查找技术
javaScript 版顺序查找算法:
1 // 顺序查找(线性查找) 只做找到即返回 2 3 // javaScript 版 4 5 function search(data,needle) 6 7 { 8 9 for(var i=0;i<data.length;i++) 10 11 { 12 13 if(data[i] == needle && typeof data[i] == typeof needle) 14 15 { 16 17 return i; 18 19 } 20 21 } 22 23 return false; 24 25 } 26 27 28 var data = [100,10,2,7,8,6]; 29 30 console.log(search(data,7));// 3 31 32 console.log(search(data,‘7‘));// false
php版顺序查找算法:
1 <?php 2 3 // php版 4 5 function search($data,$needle) 6 7 { 8 9 $data_len = count($data); 10 11 for($i=0;$i<$data_len;$i++) 12 13 { 14 15 if($data[$i] === $needle) return $i; 16 17 } 18 19 return false; 20 21 } 22 23 24 25 $data = [100,10,2,7,8,6]; 26 27 var_dump(search($data,7));// int(3) 28 29 var_dump(search($data,‘7‘));// bool(false)
python3 版顺序查找算法:
1 # python3 版本 2 3 def search(data,needle) : 4 5 dataLen = len(data) 6 7 for i in range(dataLen) : 8 9 if data[i] == needle and type(data[i]) == type(needle) : return i 10 11 return False 12 13 14 data = [100,10,2,7,8,6] 15 16 print(search(data,7)) # 3 17 18 print(search(data,‘7‘)) # False 19 20 print(search(data,6)) # 5
>>>二分找查, 折半查找
1. 用low , high , middle 表示待查找区间的 下界, 上界,中间 的坐标
2. 取中间位置 middle = floor((low+high)/2)
大于: 待查数据在区间的后半段 设low 为 middle+1
小于: 待查数据在区间的前半段 设high 为 middle-1
PHP版二分查找算法:
1 <?php 2 3 // 二分法 折半查找 PHP版 4 5 $data_list = [1,2,4,5,5,6,10,12]; 6 7 function bisearch($data_list,$needle) 8 9 { 10 11 $low = 0; 12 13 $high = count($data_list)-1; 14 15 if($data_list[$low] == $needle) return $low; 16 17 if($data_list[$high] == $needle) return $high; 18 19 while($high>=$low) 20 21 { 22 23 $middle = floor(($low+$high)/2); 24 25 if($needle == $data_list[$middle]) 26 27 { 28 29 return $middle; 30 31 }elseif($needle>$data_list[$middle]) 32 33 { 34 35 $low = $middle+1; 36 37 }else{ 38 39 $high = $middle-1; 40 41 } 42 43 } 44 45 return false; 46 47 } 48 49 50 51 print_r(bisearch($data_list,10)); // 6 52 53 print_r(bisearch($data_list,5)); // 3 54 55 print_r(bisearch($data_list,13)); // false
python 3版 二分查找算法:
1 import math 2 3 # python3 版二分查找算法 4 5 def bisearch(data_list,needle) : 6 7 low,high = 0,len(data_list)-1 8 9 if needle == data_list[low] : return low 10 11 if needle == data_list[high] : return high 12 13 while high>=low : 14 15 middle = math.floor((high+low)/2) 16 17 if needle == data_list[middle] : return middle 18 19 elif needle > data_list[middle] : low = middle+1 20 21 else : high = middle-1 22 23 return False 24 25 26 27 data_list = [1,2,4,5,5,6,10,12] 28 29 print(bisearch(data_list,10)); # 6 30 31 print(bisearch(data_list,5)); # 3 32 33 print(bisearch(data_list,13)); # False
javaScript 版二分查找算法:
1 // js 版二分查找 2 3 function bisearch(data_list,needle) 4 5 { 6 7 var low = 0,high = data_list.length-1 8 9 if (needle == data_list[low] ) return low 10 11 if (needle == data_list[high]) return high 12 13 while (high>=low) 14 15 { 16 17 var middle = Math.floor((low+high)/2) 18 19 if(needle == data_list[middle]) 20 21 { 22 23 return middle 24 25 }else if(needle>data_list[middle]) 26 27 { 28 29 low = middle + 1 30 31 }else{ 32 33 high = middle - 1 34 35 } 36 37 } 38 39 return false 40 41 } 42 43 data_list = [1,2,4,5,5,6,10,12] 44 45 console.log(bisearch(data_list,10)); // 6 46 47 console.log(bisearch(data_list,5)); // 3 48 49 console.log(bisearch(data_list,13)); // False
>>> 插值查找 (由二分查找改进)
middle = (low+high)/2 => low+(1/2)*(high-low)
插值查找的公式由上面演变, 主要改进的是二分之一部分:
middle = low+((needle-data[low])/(data[high]-data[low]))*(high-low)
对二分查找跟插值查找的一个说明:
插值查找对于公布均匀的数据, 速度比二分查找快(插值查找次数少),例如对下面这类数据
$data = [1,2,3,6,7,9,10,11,...]
$data = [4,100,300,685,3452,...]
PHP版 插值查找算法:
1 <?php 2 3 // 二分查找优化(插值查找) PHP版 4 5 $data_list = [1,2,4,5,5,6,10,12]; 6 7 function interpolation($data_list,$needle) 8 9 { 10 11 $low = 0; 12 13 $high = count($data_list)-1; 14 15 if($data_list[$low] == $needle) return $low; 16 17 if($data_list[$high] == $needle) return $high; 18 19 while($high>=$low) 20 21 { 22 23 $middle = floor($low+(($needle-$data_list[$low])/($data_list[$high]-$data_list[$low]))*($high-$low)); 24 25 if($needle == $data_list[$middle]) 26 27 { 28 29 return $middle; 30 31 }elseif($needle>$data_list[$middle]) 32 33 { 34 35 $low = $middle+1; 36 37 }else{ 38 39 $high = $middle-1; 40 41 } 42 43 } 44 45 return false; 46 47 } 48 49 50 51 print(interpolation($data_list,10)); // 6 52 53 print(interpolation($data_list,5)); // 3 54 55 print(interpolation($data_list,13)); // false 56 57 58 59 $index = interpolation($data_list,10); 60 61 echo $data_list[$index];// 10 62 63 64 /* 65 66 注: 1.floor 返回的是浮点数 如 6 类型为float 67 68 2.false 用print,echo 输出是空字符串 69 70 */
python3版 插值查找算法:
1 import math 2 3 # python3 插值查找算法 4 5 def interpolation(data_list,needle) : 6 7 low,high = 0,len(data_list)-1 8 9 if needle == data_list[low] : return low 10 11 if needle == data_list[high] : return high 12 13 while high>=low : 14 15 middle = math.floor( 16 17 low+ 18 19 ((needle-data_list[low])/(data_list[high]-data_list[low]))* 20 21 (high-low) 22 23 ) 24 25 if needle == data_list[middle] : return middle 26 27 elif needle > data_list[middle] : low = middle+1 28 29 else : high = middle-1 30 31 return False 32 33 34 35 data_list = [1,2,4,5,5,6,10,12] 36 37 print(interpolation(data_list,10)); # 6 38 39 print(interpolation(data_list,5)); # 3 40 41 print(interpolation(data_list,13)); # False
js 版插值查找算法:
1 // js版 插值查找算法 2 3 function interpolation(data_list,needle) 4 5 { 6 7 var low = 0,high = data_list.length-1 8 9 if (needle == data_list[low] ) return low 10 11 if (needle == data_list[high]) return high 12 13 while (high>=low) 14 15 { 16 17 var middle = Math.floor( 18 19 low+((needle-data_list[low])/(data_list[high]-data_list[low]))* 20 21 (high-low) 22 23 ) 24 25 if(needle == data_list[middle]) 26 27 { 28 29 return middle 30 31 }else if(needle>data_list[middle]) 32 33 { 34 35 low = middle + 1 36 37 }else{ 38 39 high = middle - 1 40 41 } 42 43 } 44 45 return false 46 47 } 48 49 data_list = [1,2,4,5,5,6,10,12] 50 51 console.log(interpolation(data_list,10)); // 6 52 53 console.log(interpolation(data_list,5)); // 3 54 55 console.log(interpolation(data_list,13)); // False
小结: