列表中查找数据有两种方法:顺序查找和二分查找。顺序查找使用于元素随机排列的列表;二分查找适用于元素已排序的列表。二分查找效率高,但是必须花费额外时间将列表中的元素排序
顺序查找
时间复杂度:O(n)
function seqSearch(arr,data){
for(var i=0;i<arr.length;i++){
if(arr[i] == data){
return true;
}
}
return false;
}
//返回匹配到的位置信息
function seqSearch(arr,data){
for(var i=0;i<arr.length;i++){
if(arr[i] == data){
return i;
}
}
return -1;
}
上述方法通过使用js的内置函数indexOf可以达到同样的效果,如果没有则返回-1,如果有则返回位置下标
使用自组织数据
原理:通过将频繁查找到的元素放在数组的起始位置,减少查找的次数,数据的查找遵循‘80-20’原则,即80%的操作都是对20%的数据进行查找,自组织的方法最终将这20%的数据移动到开始位置
//每查找一次就将其向前移动一个位置,如果查找次数够多,则会移动到数组的第一个为位置
function controlSearch(arr,data){
for(var i=0;i<arr.length;i++){
var temp;
if(arr[i] == data){
if(i>0){
temp = arr[i-1];
arr[i-1] = arr[i];
arr[i] = temp;
}
return true;
}
}
return false;
}
更好的自组织数据
原理:如果元素已经很接近起始位置,则不会移动,如果在20%之外,则将其移动到第一个位置
function controlSearch(arr,data){
for(var i=0;i<arr.length;i++){
var temp;
if(arr[i] == data && i > (arr.length*0.2)){
temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
return arr;
}else if(arr[i] == data){
return arr;
}
}
return false;
}
二分查找
算法描述:
(1)将数组的第一个位置设置为下边界(0);
(2)将数组最后一个元素所在位置设置为上边界(数组长度减1)
(3)如下边界等于或小于上边界,则做如下操作
a. 将中点设置为(上边界加下边界)除以2
b. 如果中点的元素小于查询的值,则将下边界设置为中点元素所在下标加 1。
c. 如果中点的元素大于查询的值,则将上边界设置为中点元素所在下标减 1。
d. 否则中点元素即为要查找的数据,可以进行返回。
时间复杂度:O(logn)
function binSearch(arr,data){
var left = 0;
var right = arr.length-1;
var mid;
while (left<=right){
mid = Math.floor((left+right)/2);
if(arr[mid] < data){
left = mid+1;
}else if(arr[mid] > data){
right = mid-1;
}else{
return mid;
}
}
return -1;
}
计算重复次数
如果查找的元素在数组中重复出现,则找到的位置在这些位置的中间,可以根据这个特性可以计算重复值的个数
function count(arr,data){
var count =0;
var i = binSearch(arr,data);
if(i > -1){
count++;
//向右查找,如果不相等了就退出循环
for(var j = i+1;j<arr.length;j++){
if(arr[j] == data){
count++;
}else{
break;
}
}
//向左查找,如果不相等了就退出循环
for(var j = i-1;j>0;j--){
if(arr[j] == data){
count++;
}else{
break;
}
}
}
return count;
}