2019独角兽企业重金招聘Python工程师标准>>>
1 二分查找
算法思想:
二分查找要求元素排列有序。首先,假设表中元素是按升序排列,将数组中间位置的元素与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将数组分成前、后两个子数组,如果中间位置记录的元素大于查找关键字,则进一步查找前一子数组,否则进一步查找后一子数组。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
二分查找的时间复杂度为O(logN)
算法实现:
递归算法:
//递归算法
public int rank(Key key, int lo, int hi) {if(hi<lo) return lo;int mid = lo + (hi-lo)/2;int cmp = key.compareTo(keys[mid]);if(cmp<0) return rank(key,lo,hi-1);if(cmp>0) return rank(key,mid+1,hi);else return mid;
}
非递归算法:
//非递归算法
public int rank(Key key) {int lo = 0, hi = N-1;while(lo<=hi) {int mid = lo + (hi-lo)/2;int cmp = key.compareTo(keys[mid]);if(cmp<0) hi = mid-1;if(cmp>0) lo = mid+1;else return mid;}return lo;
}
2 二叉查找树
定义:
二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
- 若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
- 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
- 左、右子树也分别为二叉排序树;
步骤:
若根结点的关键字值等于查找的关键字,成功。否则,若小于根结点的关键字值,递归查左子树。若大于根结点的关键字值,递归查右子树。若子树为空,查找不成功。
二叉查找树的时间复杂度为O(logN)
算法实现:
结点类:
private class Node{private Key key;private Value val;private Node left,right;private int N;public Node(Key key,Value val, int N) { this.key = key; this.val = val; this.N = N; }
}
其中N为以该节点为根的子树的节点总数,计算方法如下:
size(x) = size(x.left) + size(x.right) + 1
查找方法:
递归查找,如果小于当前结点,递归去左子树查找;如果大于当前结点,递归去右子树查找。
public Value get(Key key) {return get(root,key);
}
public Value get(Node x,Key key) {if(x==null)return null;int cmp = key.compareTo(x.key);if(cmp<0) return get(x.left,key);if(cmp>0) return get(x.right,key);else return x.val;
}
插入方法:
先查找,如果树中已经存在相应的键,只需更新值;如果查询无果,指针也已经指向了应该插入的位置,用要插入的键值对新创结点并插入到相关位置。
public void put(Key key,Value val) {root = put(root,key,val);
}
private Node put(Node x,Key key,Value val) {if(x == null) return new Node(key,val,1);int cmp = key.compareTo(x.key);if(cmp<0) x.left = put(x.left,key,val);//插入左子树if(cmp>0) x.right = put(x.right,key,val);//插入右子树else x.val = val;//更新值x.N = size(x.left) + size(x.right)+1;return x;
}
删除方法:
- 即将被删除的节点记为t
- x指向它的后继节点min(t.right)
- 将x的右链接链接到x的父节点的左链接上(即替换掉原x的位置)
- 用x节点替换t节点(将t.left和t.right设为x.left和x.right)
public void delete(Key key) {root = delete(root,key);
}
private Node delete(Node x,Key key) {if(x == null) return null;int cmp = key.compareTo(x.key);if(cmp<0) x.left = delete(x.left,key);if(cmp>0) x.right = delete(x.right,key);else {if(x.right == null) return x.left;if(x.left == null) return x.right;Node t = x;x = min(t.right);x.right = deleteMin(t.right);x.left = t.left;}x.N = size(x.left)+size(x.right)+1;return x;
}