三分查找(Ternary Search),查找一次就可以排除整個有序線性表的2/3,查找效率更高。最差時間複雜度O(log3 n),最優時間複雜度
O(1),空間複雜度O(1)。
Java代碼示例:
/**
* 使用遞歸的方法
* 三分數組搜索
* @param arr 數組
* @param key 目標數值
* @param s 數組下標開始位置
* @param e 數組下標結束位置
* @return 目標下標位
*/
public int ternaryFind(int[] arr, int key, int s, int e){
if (s < e){
return -1;
}
// 第一個範圍點數組長度的1/3
int midPos1 = s + (e - s)/3;
// 第二個範圍點數組長度的2/3
int midPos2 = s + 2*(e - s)/3;
if (key == arr[midPos1]){
return midPos1;
}else if (key == arr[midPos2]){
return midPos2;
}else if (key < arr[midPos1]){
return ternaryFind(arr, key, s, midPos1-1);
}else if (key > arr[midPos2]){
return ternaryFind(arr, key, midPos2 + 1, e);
}else {
return ternaryFind(arr, key, midPos1 + 1, midPos2 - 1);
}
}
public<T extends Comparable<T>> int ternaryFind(T[] arr, T key, int s, int e){
if (s > e){
return -1;
}
int midPos1 = s + (e - s)/3;
int midPos2 = s + 2*(e - s)/3;
int cmpResult1 = key.compareTo(arr[midPos1]);
int cmpResult2 = key.compareTo(arr[midPos2]);
if (cmpResult1 == 0){
return midPos1;
}else if (cmpResult2 == 0){
return midPos2;
}else if (cmpResult1 < 0){
return ternaryFind(arr, key, s, midPos1 - 1);
}else if (cmpResult2 > 0){
return ternaryFind(arr, key, midPos2 + 1, e);
}else {
return ternaryFind(arr, key, midPos1 + 1, midPos2 - 1);
}
}
/**
* 三分搜索法
* 迭代循環
* @param arr 數組
* @param key 目標對象
* @param s 數組下標開始位
* @param e 數組下標結束位
* @param <T> 泛型
* @return 目標下標位置
*/
public<T extends Comparable<T>> int ternaryFindCycle(T[] arr, T key, int s, int e){
/**
* 1、一次循環排除2/3
* 推薦
*/
while (s >=0 && e >= s){
int midPos1 = s + (e - s)/3;
int midPos2 = s + 2*(e - s)/3;
int cmpResult1 = key.compareTo(arr[midPos1]);
int cmpResult2 = key.compareTo(arr[midPos2]);
if (cmpResult1 == 0){
return midPos1;
}else if (cmpResult2 == 0){
return midPos2;
}else if (cmpResult1 < 0){
e = midPos1 - 1;
}else if (cmpResult2 > 0){
s = midPos2 + 1;
}else {
s = midPos1 + 1;
e = midPos2 - 1;
}
}
/**
* 2、一次循環排除1/3或者2/3
* 不推薦
*/
while (s >=0 && e >= s){
int midPos1 = s + (e - s)/3;
int cmpResult1 = key.compareTo(arr[midPos1]);
if (cmpResult1 == 0){
return midPos1;
}else if (cmpResult1 < 0){
e = midPos1 - 1;
}else {
s = midPos1 + 1;
}
}
return -1;
}