符号表 C++

符号表是一张抽象的表格, 将信息存储到里面, 可以按指定的键来搜索获取这些信息,且键不能重复。 例如:数据库。

编译器可以用符号表来根据变量名来找到对应的值和类型。

无序链表的符号表:

用链表实现的符号表
符号表的API为

void put(KEY k, VAL v); //插入值
VAL get(KEY k); //得到对应键的值
void delete(KEY k); //删除键为k的键和值
bool contains(KEY k); //表中是否包含键k
bool is_empty(KEY k); //表是否为空
int size(); //表中的元素数
KEY max(); //最大的键
KEY min(); //最小的键

其中插入操作比较特殊
先遍历链表, 查找表中是否已经存在键k, 若存在,则改变键k的val值, val = v; 若不存在, 新建一个节点插入到表头。

void put(KEY k, VAL v){
     for(node<KEY, VAL> *t = first; t != NULL; t = t->next)
     if(t->key == k){t->val = v; return;}
     first = new node<KEY, VAL>(k, v, first);
}

完整的代码实现如下:

#include<iostream>
using namespace std;
template <class KEY, class VAL>
class node{
    public:
    KEY key;
    VAL val;
    node<KEY, VAL> *next;
    node<KEY, VAL> (){key = NULL; val = NULL; next = NULL;}
    node<KEY, VAL>(KEY k, VAL v, node<KEY, VAL> *n){key = k; val = v; next = n;}
};
template <class KEY, class VAL>
class Seq_search_ST{
    node<KEY, VAL> *first;
    public:
    Seq_search_ST(){first = new node<KEY, VAL>(); first = NULL;}
    void put(KEY k, VAL v){
        for(node<KEY, VAL> *t = first; t != NULL; t = t->next)
           if(t->key == k) {t->val = v; return;}
        first = new node<KEY, VAL>(k, v, first);
    }
    VAL get(KEY k){
        for(node<KEY, VAL> *t = first; t != NULL; t = t->next)
           if(t->key == k) return t->val;
        return NULL;
    }
    void del(KEY k){
        if(first->key == k){first = first->next; return;}
        for(node<KEY, VAL> *t = first; t != NULL; t = t->next)
           if(t->next->key == k){t ->next = t->next->next; return;}
        cout << "key is not exist\n";
    }
    bool contains(KEY k){
        for(node<KEY, VAL> *t = first; t != NULL; t = t->next)
           if(t->key == k) return true;
        return false;
    }
    bool is_empty(){return first->key == NULL;}
    int size(){
        int cnt = 0;
        for(node<KEY, VAL> *t = first; t != NULL; t = t->next) cnt++;
        return cnt;
    }
    KEY Min(){
       VAL min_val = first->val;
       KEY min_key = first->key;
        for(node<KEY, VAL> *t = first->next; t != NULL; t = t->next)
           if(t->val < min_val) {min_val = t->val; min_key = t->key;} 
        return min_key;
    }
    KEY Max(){
        VAL max_val = first->val;
       KEY max_key = first->key;
        for(node<KEY, VAL> *t = first->next; t != NULL; t = t->next)
           if(t->val > max_val) {max_val = t->val; max_key = t->key;} 
        return max_key;
    }
};
int main(){
    Seq_search_ST<int, double> st;
    st.put(1,4);
    st.put(2,5);
    cout << st.Min();
    return 0;
}

有序数组的符号表

因为用链表实现, 插入和删除操作很慢, 所以有了用有序数组存储的符号表, 基于二分查找。

核心操作为

int rank(KEY k){
    int lo = 0, hi = N - 1;
    while(lo <= hi){
         int mid = lo + (hi - lo) / 2;
         if(keys[mid] < k) lo = mid + 1;
         else if(keys[mid] > k) hi = mid - 1;
         else return mid;
    }
    return lo;
}

该函数可返回小于键k的个数。

插入操作:
先调用rank函数, 判断表中是否已经存在键k, 若存在, 则更新键k的val, 若不存在, 把rank的返回值后面的数值中的值都往后移一位, 然后插入。

删除操作:
调用rank函数, 返回其键k的位置, 删除, 若不存在键k, 直接返回。

#include<iostream>
using namespace std;
template <class KEY, class VAL>
class Binary_search_ST{
    KEY *keys;
    VAL *vals;
    int N;
    public:
    Binary_search_ST(int capacity){keys = new KEY[capacity]; vals = new VAL[capacity]; N = 0;}
    int rank(KEY k){
        int lo = 0, hi = N-1;   
        while(lo <= hi){
            int mid = lo + (hi - lo) / 2;
            if(keys[mid] < k) lo = mid + 1;
            else if(keys[mid] > k) hi = mid - 1;
            else return mid;
        }
        return lo;
    }
    void put(KEY k, VAL v){
        int i = rank(k);
        if(i < N && keys[i] == k){vals[i] = v; return;}
        for(int j = N; j > i; --j){keys[j] = keys[j-1]; vals[j] = vals[j-1];}
        keys[i] = k; vals[i] = v;
        N++;
    }
    VAL get(KEY k){
        if(N == 0) return NULL;
        int i = rank(k);
        if(i < N && keys[i] == k) return vals[i];
        return NULL;
    }
    void del(KEY k){
        int i = rank(k);
        if(i < N && keys[i] == k){
            if(i == N-1) {N--; return;}
            for(int j = N - 1; j > i; --j){
                keys[j-1] = keys[j];
                vals[j-1] = vals[j];        
            }
            N--;    
        }
        else cout << "key is not exist\n";
    }
    bool contains(KEY k){
        int i = rank(k);
        if(i < N && keys[i] == k) return true;
        return false;
    }
    KEY min(){
        return keys[0];
    }
    KEY max(){
        return keys[N-1];
    }
    KEY ceiling(KEY k){
        int i = rank(k);
        
    }

};
int main(){
    Binary_search_ST<int, double> st(10);
    st.put(1, 2);
    st.put(2, 3);
    //st.del(2);
    if(st.contains(2))
    cout << "yes\n";
    
    return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值