zoukankan      html  css  js  c++  java
  • 数据结构之散列表

    散列表

    • 实现一个基于链表法解决冲突问题的散列表
    • 实现一个LRU缓存淘汰算法

     /*链接法解决哈希散列碰撞问题*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
     
    #define N 20      //数组数量
    #define Nhash 7  //哈希槽的数量
    #define N_R 200
     
    //每个数据结点
    typedef struct node{
        int key;
        int num;
        struct node * next;
        struct node * pre;
    }Node, *Pnode;
     
    //哈希链表
    typedef struct Hash{
        Pnode link[N]; //每个链表的表头指针
        int num;    //哈希表中现存数据
        int len;     //哈希数组长度
    }hash,*Phash;
     
    Pnode IniPnode(int key){
        Pnode p=(Pnode)malloc(sizeof(Node));
        p->key=key;
        p->num=1;
        p->next=NULL;
        p->pre=NULL;
    }
     
    //散列位置计算,当前使用取余数法
    int HashPos(int key){
        return key % Nhash;
    }
     
    Pnode FindNodePos(Phash h, int key){
        int pos=HashPos(key);
        Pnode link = h->link[pos];
        while(link->next != NULL && link->key != key){
            link=link->next;
        }
        return link;   
    }
     
    void IniHash(Phash *h, int len){
        int i;
        *h=(Phash)malloc(sizeof(hash));
        for(i=0;i<len;i++){
            (*h)->link[i] = IniPnode(-1); //头结点
        }
        (*h)->num =0;  //总数为0
        (*h)->len=len;
    }
     
    void Insert(Phash h, int key){
        Pnode p=FindNodePos(h,key);
        if(p->next != NULL) p->num ++;
        else{
            Pnode q =IniPnode(key);
            p->next = q;
            q->pre=p;      
        }
         ++ h->num ;
    }
     
    Pnode Search(Phash h, int key){
        Pnode p=FindNodePos(h,key);
        if(p->next = NULL) return NULL;
        else return p;    
    }
     
    int Delete(Phash h, int key){
        Pnode p=FindNodePos(h,key);
        p->pre->next=p->next;
        free(p);
    }
     
    void PrintLink(Pnode p){
        while(p->next!=NULL){
            printf("[key=%d|num=%d] -> ",p->next->key,p->next->num);
            p=p->next;
        }
        //printf("[key=%d|num=%d]",p->key,p->num);
        printf(" ");
    }
     
    void PrintHash(Phash h){
        int i;
        printf("哈希表中公有结点%d个 ",h->num);
        for(i=0;i<h->len;i++){
            printf("%d ",i);
            PrintLink(h->link[i]);
        }
    }
     
    void DeleteHash(Phash h){
        int i;
        for(i=0;i<h->num;i++){
            free(h->link[i]);
        }
        free(h);
    }
        
    int main(){
        int i, a[N];
        Phash h=NULL; //哈希数组链表头结点  
        IniHash(&h,Nhash);  
               
        srand((unsigned)time(NULL));    
        for(i=0;i<N;i++){
            a[i]=rand()%N_R;
            Insert(h,a[i]);
            printf("%d ",a[i]);       
        }
        printf(" ");
        PrintHash(h);
        for(i=0;i<N;i++){
            Delete(h,a[i]);
        }       
        DeleteHash(h);
        system("pause");
        return 0;
    }
    # -*- coding: utf-8 -*-
    """

    """
    class Node:
        def __init__(self,key,value):
            self.key=key
            self.value=value
            self.next=None
            
     
    class ChainHash:
        def __init__(self,capacity):
             self.capacity=capacity
             self.table=[None]*capacity
        def buildHash(self,lista):
            for i in range(len(lista)):
                value=int(lista[i])
                key=value % 13
                print(key)
                node_=self.table[key]
            
                if node_ is None:
                    self.table[key]=Node(key,value)
                else:
                    while node_.next is not None:
                        if node_.key == key:
                            node_.value = value
                            return
                        node_ = node_.next
                    node_.next = Node(key, value)
            
        
            
        def InsertHash(self,value):
            key=value % 13
            node_=self.table[key]
            if node_ is None:
                self.table[key]=Node(key,value)
            else:
                while node_.next is not None:
                    if node_.key == key:
                        node_.value = value
                        return
                    node_ = node_.next
                node_.next = Node(key, value)
                
        def SearchHash(self,key,value):
            node_ = self.table[key]
            while node_ is not None:
                if node_.value == value:
                    return node_ # 返回该指针位置
                node_ = node_.next
            return None    # 若没有找到该数值,则返回空
    # In[]
    if __name__ == '__main__':
        s=ChainHash(20)
        lista=[1,6,11,14,19]
        
        # In[]
        s.buildHash(lista)
            # In[]
        s.InsertHash(27)
    #    print(s.table)
         # In[]
        print(s.SearchHash(1,17))
        

    LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

    原理:

    利用list记录key的次序,每次set,或get操作将key插入到list首位。

    缓冲区满之后再出现set操作,移除末尾的key。

    key in dict判断key是否出现过

        class LRUcache:
            def __init__(self, size=3):
                self.cache = {}
                self.keys = []
                self.size = size
         
            def get(self, key):
                if key in self.cache:
                    self.keys.remove(key)
                    self.keys.insert(0, key)
                    return self.cache[key]
                else:
                    return None
         
            def set(self, key, value):
                if key in self.cache:
                    self.keys.remove(key)
                    self.keys.insert(0, key)
                    self.cache[key] = value
                elif len(self.keys) == self.size:
                    old = self.keys.pop()
                    self.cache.pop(old)
                    self.keys.insert(0, key)
                    self.cache[key] = value
                else:
                    self.keys.insert(0, key)
                    self.cache[key] = value
         
        if __name__ == '__main__':
            test = LRUcache()
            test.set('a',2)
            test.set('b',2)
            test.set('c',2)
            test.set('d',2)
            test.set('e',2)
            test.set('f',2)
            print(test.get('c'))
            print(test.get('b'))
            print(test.get('a'))

  • 相关阅读:
    DataTables合并单元格(rowspan)的实现思路(多分组分类的情况)
    DataTables固定表格宽度(设置横向滚动条)
    用图片替代cursor光标样式
    DataTables获取指定元素的行数据
    任意表格(table)实现拖动列(column)改变列大小
    鼠标拖动改变DIV等网页元素的大小的最佳实践
    DataTables实现rowspan思路
    DataTables添加额外的查询参数和删除columns等无用参数
    击穿(强推---神仙代码)
    java jvm 参数 -Xms -Xmx -Xmn -Xss 调优总结
  • 原文地址:https://www.cnblogs.com/hrnn/p/13347261.html
Copyright © 2011-2022 走看看