zoukankan      html  css  js  c++  java
  • 算法4-6:关联数组的基本实现

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


    链表法


    一种方法就是用链表进行实现。这样的方法的基本思想就是用链表储存键值对。当须要寻找一个值时,扫描整个链表,假设有匹配的键,就返回相应的值。当须要插入一个值时,扫描整个链表,假设可以找到匹配的键,就覆盖相应的值,假设没有找到,就在链表的头部添加一个新的键值对。


    这样的算法查找操作和插入操作的复杂度均为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);
     
            // 假设找到了相应的keyword
            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;
        }
    }


    结论


    因此须要一种算法可以实现查找和插入操作的复杂度都非常低。


  • 相关阅读:
    Web发布cab文件打包的ActiveX控件总结 (转)
    【转】GLSL语言内置变量(转)
    osg学习 osg源码分析最长的一帧 第五日
    利用ATL技术创建ActiveX控件CircleCtl 。简单介绍 VC2003 使用 ATL 开发 ActiveX 控件(转)
    不用安装界面器实现系统支持xvid编码器
    BitBlt 注意事项(CAPTUREBLT) (转)
    使用ATL开发ActiveX控件
    Ossimplanet编译笔记(VS2008)(转载)
    端午小长假谨防挂马网站 病毒模仿杀软骗取钱财 狼人:
    2009年度全球顶级杀毒软件(性价比)排名 狼人:
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4003546.html
Copyright © 2011-2022 走看看