算法--查找

2人阅读 评论(0) 收藏 举报
分类:

无序链表中的顺序查找


import edu.princeton.cs.algs4.Stack;
/**
 * 算法 3.1  顺序查找(基于无序链表)
 * @author he
 */
public class SequentialSearchST<Key, Value> {
private Node first;// 链表首结点
private int N; // 链表元素个数
private class Node {
Key key;
Value value;
Node next;
public Node(Key key, Value value, Node next) {
this.key = key;
this.value = value;
this.next = next;
}
}
/**
* 根据键获取值
* @param key
* @return
*/
public Value get(Key key) {
if (key == null) {
throw new NullPointerException("key can't be null");
}
for (Node x = first; x != null; x = x.next) {
if (x.key.equals(key)) {
return x.value; // 命中
}
}
return null;// 未命中
}
/**
* 向链表中添加新的键值对
* @param key
* @param value
*/
public void put(Key key, Value value) {
if (key == null) {
throw new NullPointerException("key can't be null");
}
for (Node x = first; x != null; x = x.next) {
if (key.equals(x.key)) {
x.value = value;// 命中 更新value值
return;
}
}
first = new Node(key, value, first);// 未命中,新结点
N++;
}
// 元素个数
public int size() {
return N;
}
public boolean isEmpty() {
return N == 0;
}
public boolean contains(Key key) {
if (key == null)
throw new NullPointerException("key 不能为null");
return get(key) != null;
}
/**
* 根据键删除指定键值对
* @param key
*/
public void delete(Key key) {
if (key == null)
throw new NullPointerException("key 不能为 null");
first = delete(first, key);
}
private Node delete(Node x, Key key) {
if (x == null) {
return null;
}
if (x.key.equals(key)) {
N--;
return x.next;
}
x.next = delete(x.next, key);
return x;
}
/**
* 因为链表的实现时以栈的形式,所以这里使用栈,这样就能保证return后得到的顺序数put时的顺序
* @return
*/
public Iterable<Key> keys() {
Stack<Key> stack = new Stack<Key>();
for (Node x = first; x != null; x = x.next)
stack.push(x.key);
return stack;
}
public static void main(String[] args) {
SequentialSearchST<String, Integer> st = new SequentialSearchST<String, Integer>();
st.put("A", 3);
st.put("B", 2);
st.put("C", 1);
System.out.println(st.get("A"));
st.delete("A");
System.out.println(st.size());// 2
System.out.println(st.get("B"));// null
for (String s : st.keys()) {
System.out.print(s);
}
}

}



有序数组中的二分查找




import edu.princeton.cs.algs4.Queue;
/**
 * P239 算法3.2 二分查找(基于有序数组)
 * @author he
 */
public class BinarySearchST<Key extends Comparable<Key>, Value> {
private Key keys[];
private Value values[];
private int N = 0;// 元素数量
@SuppressWarnings("unchecked")
public BinarySearchST(int capacity) {
keys = (Key[]) new Comparable[capacity];
values = (Value[]) new Object[capacity];
}
public int size() {
return N;
}
public boolean isEmpty() {
return N == 0;
}
/**
* 根据Key返回对应的Value
* @param key
* @return
*/
public Value get(Key key) {
if (key == null) {
throw new RuntimeException("key can't be null");
}
if (isEmpty()) {
return null;
}
int i = rank(key);
if (i < N && keys[i].compareTo(key) == 0) {
return values[i];
} else {
return null;
}
}
/**
* 二分查找,如过存在返回键的index,如果不存在返回小于它的键的数量,因为lo在迭代时改变
* @param key
* @return
*/
public int rank(Key key) {
int lo = 0, hi = N - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
int t = key.compareTo(keys[mid]);
if (t > 0) {
lo = mid + 1;
} else if (t < 0) {
hi = mid - 1;
} else {
return mid;
}
}
return lo;
}
/**
* 向符号表中添加键值对
* @param key
* @param value
*/
public void put(Key key, Value value) {
if (key == null) {
throw new RuntimeException("key can't be null");
}
int i = rank(key);
// 命中,已存在,更新
if (i < N && keys[i].compareTo(key) == 0) {
values[i] = value;
return;
}
// 未命中添加,此时是有序添加
for (int j = N; j > i; j--) {
keys[j] = keys[j - 1];
values[j] = values[j - 1];
}
keys[i] = key;
values[i] = value;
N++;
}
/**
* 根据key删除键值对 将该键后面的键前移
* @param key
*/
public void delete(Key key) {
if (key == null) {
throw new RuntimeException("key can't be null");
}
int i = rank(key);
// 不包含key
if (i == N || keys[i].compareTo(key) != 0) {
return;
}
for (int j = i; j < N - 1; j++) {
keys[j] = keys[j + 1];
values[j] = values[j + 1];
}
keys[N - 1] = null;
values[N - 1] = null;
N--;
}
// 返回最小键
public Key min() {
return keys[0];
}
public Key max() {
return keys[N - 1];
}
/**
* 根据下标找key
* @param k
*            下标
* @return
*/
public Key select(int k) {
return keys[k];
}
/**
* 大于等于该键的最小键
* @param key
* @return
*/
public Key ceiling(Key key) {
// 因为rank做了处理,所以即使未找到key人能返回刚好比key大的index
int i = rank(key);
return keys[i];
}
/**
* 小于等于该键的最大键
* @param key
* @return
*/
public Key floor(Key key) {
// 有该键
if (get(key) != null) {
return keys[rank(key)];
} else if (get(key) == null && rank(key) != 0) {// 不存在该键且rank(key)不再数组最左边
return keys[rank(key) - 1];
} else {
return null;
}
}
public Iterable<Key> key(){
Queue<Key> queue=new Queue<Key>();
for(int i=0;i<N;i++){
queue.enqueue(keys[i]);
}
return queue;
}
public static void main(String[] args) {
BinarySearchST<String, Integer> st = new BinarySearchST<String, Integer>(10);
st.put("A", 3);
st.put("C", 2);
st.put("B", 1);
System.out.println(st.key());//A B C
System.out.println(st.get("B"));
System.out.println(st.ceiling("D"));// null
st.delete("A");
System.out.println(st.get("A"));// null
System.out.println(st.floor("A"));// null
System.out.println(st.key());// B C
}

}


递归的rank()保留了以下性质:

如果表中存在该键,rank()应该返回该键的位置,也就是表中小于它的键的数量;

如果表中不存在该键,rank()还是应该返回表中小于它的键的数量;









查看评论

中国科大算法之查找部分

  • 2009年07月13日 13:57
  • 248KB
  • 下载

子字符串查找算法_归纳及汇总

字符串的一种基本操作就是子字符串查找:给定一段长度为N的文本和一段长度为M的模式字符串,在文本中找到一个和该模式相符的字符串。 模式-> ABCDE 正文-> SJAHDJKS”ABCDE”...
  • JonsTank2013
  • JonsTank2013
  • 2016-03-15 17:44:31
  • 4857

算法#15--子字符串查找算法汇总和代码详解

子字符串查找算法汇总和代码详解。
  • tclxspy
  • tclxspy
  • 2016-09-22 14:08:53
  • 1469

基本的查找算法示例

顺序查找-比较简单,循环比较即可/*Find*/ //顺序查找算法,循环比较即可 #include #include #define N 15 using namespace std; int S...
  • v_xchen_v
  • v_xchen_v
  • 2016-07-18 11:35:42
  • 544

数据结构与算法:查找

所谓查找(Search)又称检索,就是在一个数据元素集合中寻找满足某种条件的数据元素。查找在计算机数据处理中是经常使用的操作。查找算法的效率高低直接关系到应用系统的性能。查找的方法很多,本章将介绍一些...
  • axi295309066
  • axi295309066
  • 2017-01-04 20:45:04
  • 1561

二叉树查找的算法和演示过程

  • 2010年12月28日 14:16
  • 17KB
  • 下载

【面试必读(编程基础)】几种查找算法

http://www.cnblogs.com/maybe2030/p/4715035.html?utm_source=tuicool&utm_medium=referral 查找是在...
  • chrisfxs
  • chrisfxs
  • 2017-04-18 19:51:43
  • 2116

排序和查找算法

排序和查找是两种典型的算法1 排序算法冒泡排序算法是最简单的排序算法,它的执行效率最低,但冒泡排序算法既适用于顺序物理结构也适用于链式物理结构 冒泡排序任何时候比较的都是相邻的两个数,而选择排序是固...
  • Robot__Man
  • Robot__Man
  • 2016-09-09 23:51:33
  • 788

区间表的快速查找算法

  • 2012年03月16日 10:31
  • 220KB
  • 下载

数组鞍点算法

书上只有算法,我还是觉得在机子上过一遍的好。。。。。 //鞍点:aij是第i行中最小值且是第j列中的最大值,则该元素是矩阵一个鞍点。找出矩阵中的所有鞍点 //矩阵鞍点算法 #include ...
  • hedafighter2011
  • hedafighter2011
  • 2012-10-23 11:18:18
  • 2449
    个人资料
    持之以恒
    等级:
    访问量: 244
    积分: 223
    排名: 34万+
    文章存档