顺序查找
又叫做顺序查找,查找过程:从表中第一个(或最后一个)记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果直到最后一个(或第一个)记录,其关键字和给定值比较都不相等,则表中没有所查的记录,查找不成功。
查找算法实现:
// a为数组,n为要查找的数组长度,key为要查找的关键字
function sequentialSearch(a, n, key) {
var i;
for (i=1; i<n; i++) {
if (a[i] === key) {
return i;
}
}
return 0;
}
该实现每次勋魂时都需要对i是否越界,即是否小于等于n作判断。
优化实现(设置哨兵):
function sequentialSearch2(a, n, key) {
var i = 0;
a[n] = key;
while (a[i] !== a[n]) {
i++;
}
return i < n ? i+1 : 0;
}
折半查找
折半查找(Binary Search)技术,又称为二分查找。前提线性表中的记录必须关键码有序,线性表必须采用顺序存储。在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区域继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。
function binarySearch(a, n, key) {
var low, high, mid;
low = 0;
high = n - 1;
while (low <= high) {
mid = Math.floor((low + high) / 2);
if (key < a[mid]) {
high = mid - 1;
} else if (key > a[mid]) {
low = mid + 1;
} else {
return mid + 1;
}
}
return 0;
}
插值查找
插值查找(Interpolation Search)是根据要查找的关键字key与查找表中最大最小记录的关键字比较后查找方法,其核心就是插值的计算公式:(key-a[low]) / (a[high]-a[low])
function InsertionSearch(arr, val, start, end) {
var end = end || arr.length - 1;
var start = start || 0;
var mid = start + (val - arr[low]) / (arr[end] - arr[start]) * (end - start);
if (arr[mid] == val) {
return mid;
}
if (arr[mid] > val) {
return InsertionSearch(arr, val, start, mid - 1);
}
else {
return InsertionSearch(arr, val, mid + 1, end);
}
}
斐波那契查找
function search(array, value) {
let low = 0, high = array.length - 1, n = array.length - 1;
let mid, k = 0;
//构建一个长度大于array数组的斐波那契数组
var F = [];
F[0] = 0;
F[1] = 1;
for (var i = 2; i < high + 5; i++) {
F[i] = F[i - 1] + F[i - 2];
}
while (high > F[k] - 1) { //寻找第k项
k++;
}
for (let i = high; i < F[k] - 1; i++) { //补全有序数组
array[i] = array[high];
}
while (low <= high) {
mid = low + F[k - 1] - 1;
if (array[mid] > value) {
high = mid - 1;
k = k - 1; //长度缩减为F[k-1]-1
} else if (array[mid] < value) {
low = mid + 1;
k = k - 2; //长度缩减为F[k-2]-1
} else {
if (m <= n) //相等则找到位置
return mid;
else {
return n; //大于原始长度,则说明等于数组最后一项
}
}
return -1;
}
}
二叉排序树查找操作
二叉排序树(Binary Sort Tree),又称为二叉查找树。它或者是一颗空数=树,或者是具有下列性质的二叉树。
-
若它的左子树不为空,则左子树上所有的节点值均小于它的根结构的值;
-
若它的右子树不为空,则右子树上所有的节点值均大于它的根节点的值;
function TreeNode(val, left, right) { this.val = (val === undefined ? 0 : val); this.left = (left === undefined ? null : left); this.right = (right === undefined ? null : right); }
function searchBST(T, key) { if (!T) { return false; } else if (key === T.val) { return true; } else if (key < T.val) { return seatchBST(T.left, key); } else { return searchBST(T.right, key); } }
平衡二叉树:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。
function TreeNode(val, left, right) {
this.val = (val === undefined ? 0 : val);
this.left = (left === undefined ? null : left);
this.right = (right === undefined ? null : right);
}
var isBalanced = function(root) { if (!root) {return true} if (Math.abs(depth(root.left) - depth(root.right)) > 1) { return false; } return isBalanced(root.left) && isBalanced(root.right); function depth(node) { if (!node) {return 0} const left = depth(node.left); const right = depth(node.right); return Math.max(left, right) + 1; }};
对称二叉树:给定一个二叉树,检查它是否是镜像对称的。
var isSymmetric = function(root) {
if (!root) {return true;}
function leftAndRight(left, right) {
if (!left && !right) {
return true;
}
if (!left || !right) {
return false;
}
if (left.val !== right.val) {
return false;
}
return leftAndRight(left.left, right.right) && leftAndRight(left.right, right.left);
}
return leftAndRight(root.left, root.right);
};