算法4-6:关联数组的基本实现

来源:互联网 发布:海岛研究所数据大全 编辑:程序博客网 时间:2024/05/14 07:34

本节主要介绍键值对表的基本实现方法。


链表法


一种方法就是用链表进行实现。这种方法的基本思想就是用链表储存键值对。当需要寻找一个值时,扫描整个链表,如果有匹配的键,就返回对应的值。当需要插入一个值时,扫描整个链表,如果能够找到匹配的键,就覆盖对应的值,如果没有找到,就在链表的头部增加一个新的键值对。


这种算法查找操作和插入操作的复杂度均为N,性能很差。


代码

public class LinkedST<Key extends Comparable<Key>,Value> {    private class Node {        Key key;        Value value;        Node next;    }     private Node first;     public void insert(Key key, Value value) {        Node node = search(key);        if(node == null) {            node = new Node();            node.key = key;            node.value = value;            node.next = first;            first = node;        } else {            node.value = value;        }    }     public boolean isEmpty() {        return first == null;    }     public Value get(Key key) {        Node node = search(key);        if(node != null)            return node.value;        return null;    }     private Node search(Key key) {        Node node = first;        while(node != null) {            if(node.key.compareTo(key) == 0) {                return node;            }            node = node.next;        }        return null;    }}


数组法


另一种方法就是用数组进行实现。搜索的时候可以用二分查找。所以这种算法查找的复杂度时logN,但是插入的复杂度依然是N。虽然比链表稍微好一点,但是插入操作的复杂度还是太高,无法满足性能要求。


代码

public class ArrayST<Key extends Comparable<Key>, Value> {    private Key[] keys; // 注意,这里必须要两个数组分别保存key和value。如果将key和value包含在一个对象中,会导致Generic Array Creation。    private Value[] values;    private int N;     public ArrayST(int capacity) {        keys = (Key[])new Comparable[capacity];        values = (Value[])new Object[capacity];    }     private void debugPrint() {        for(int i=0;i<N;i++) {            System.out.println(keys[i]);        }    }     public void insert(Key key, Value value) {        int i = search(key);         // 如果找到了对应的关键字        if(i < N && keys[i].compareTo(key) == 0) {            // 覆盖对应的值            values[i] = value;        } else {            // 插入新的值            for(int j=N-1;j>=i;j--) {                keys[j+1] = keys[j];                values[j+1] = values[j];            }            keys[i] = key;            values[i] = value;            N++;        }    }     public Value get(Key key) {        int i = search(key);         // 如果找到了对应的键        if(i<N && keys[i].compareTo(key) == 0) {            return values[i];        }         // 找不到        return null;    }     public boolean isEmpty() {        return N==0;    }     // 二分查找    private int search(Key key) {        int lo = 0;        int hi = N;        while(lo < hi) { // 注意,这里是lo < hi,而不是lo > hi            int mid = (hi-lo)/2 + lo;            int compare = key.compareTo(keys[mid]);             // 如果key比较小,说明要找的键在左边            if(compare < 0) {                hi = mid;            } else if(compare > 0) {                // 要找的键在右边                lo = mid+1;            } else {                // 正好找到想要的键                return mid;            }        }         // 没有找到,注意:没有找到时要返回key应该插入的位置,而不是N        return lo;    }}


结论


因此需要一种算法能够实现查找和插入操作的复杂度都很低。


0 0
原创粉丝点击