散列(C++实现)

散列的构成:散列函数,散列表的存储方式,散列表的冲突解决方法。

1.散列函数

  较常用的散列函数有除留余数法,数字分析法,平方取中法,折叠法。

2.散列表的存储方式

  闭散列法(开地址法),用数组存储;开散列法(链地址法),用邻接链表存储。

3.散列表的冲突解决方法

  主要是针对闭散列中关键码位置冲突的问题,常用的方法有线性探查法,二次探查法,双散列法。

性能分析:在存储方式中,开散列法优于闭散列法;在散列函数中,除留余数法最优。

实现代码:

  1 #include<iostream>
  2 using namespace std;
  3 enum kind{Active,Empty,Deleted};
  4 class ArrayHashTable{//闭散列
  5     public:
  6         ArrayHashTable(const int d,int sz=20){
  7             tableSize=sz;
  8             divitor=d;
  9             table=new int[tableSize];
 10             info=new kind[tableSize];
 11             for(int i=0;i<tableSize;i++){
 12                 table[i]=0;
 13                 info[i]=Empty;
 14             }
 15         }
 16         ~ArrayHashTable(){
 17             delete[] table;
 18             delete[] info;
 19         }
 20         bool findPos(int k,int &i){//寻找k关键码所在位置i
 21             i=k%divitor;
 22             int j=i;
 23             do{
 24                 if(info[i]==Active&&table[i]==k)
 25                     return true;
 26                 if(info[i]==Empty)
 27                     return false;
 28                 i=(i+1)%tableSize;
 29             }
 30             while(j!=i);
 31             return false;
 32         }
 33         bool insert(int k){//插入关键码k
 34             int i;
 35             if(findPos(k,i))
 36                 return false;
 37             if(info[i]!=Active){
 38                 table[i]=k;
 39                 info[i]=Active;
 40                 return true;
 41             }else
 42                 return false;
 43         }
 44         bool remove(int k){//删除关键码k
 45             int i;
 46             if(!findPos(k,i))
 47                 return false;
 48             table[i]=Deleted;
 49             return true;
 50         }
 51         int *getArray(){
 52             return table;
 53         }
 54     private:
 55         int divitor;
 56         int tableSize;
 57         int *table;
 58         kind *info;
 59 };
 60 class Node{
 61     public:
 62         int data;
 63         Node *next;
 64         Node(int d,Node *n=NULL){
 65             data=d;
 66             next=n;
 67         }
 68 };
 69 class LinkedHashTable{
 70     public:
 71         LinkedHashTable(int d,int sz=20){
 72             tableSize=sz;
 73             divitor=d;
 74             hs=new Node*[sz];
 75             for(int i=0;i<sz;i++)
 76             hs[i]=new Node(0);
 77         }
 78         ~LinkedHashTable(){
 79             delete []hs;
 80         }
 81         bool findPos(int k,Node *&p,Node *&last){
 82             int i=k%divitor;
 83             last=hs[i];
 84             p=hs[i]->next;
 85             while(p!=NULL&&p->data!=k){
 86                 p=p->next;
 87                 last=last->next;
 88             }
 89             if(p!=NULL&&p->data==k)
 90                 return true;
 91              else
 92                  return false;
 93         }
 94         bool insert(int k){
 95             Node *p,*last;
 96             int i=k%divitor;
 97             if(findPos(k,p,last))
 98                 return false;
 99             last->next=new Node(k);
100             return true;
101         }
102         bool remove(int k){
103             Node *p,*last;
104             if(!findPos(k,p,last))
105                 return false;
106             last->next=p->next;
107             return true;
108         }
109         Node **getArray(){
110             return hs;
111         }
112     private:
113         int divitor;
114         int tableSize;
115         Node **hs;
116 };
117
118 void test(Node *&q){
119     q=new Node(4);
120 }
121 int main(){
122 //    ArrayHashTable *hs=new ArrayHashTable(11,12);
123 //    int a[]={37,25,14,36,49,68,57,11};
124 //    for(int i=0;i<8;i++)
125 //        hs->insert(a[i]);
126 //    int *array=hs->getArray();
127 //    for(int i=0;i<12;i++){
128 //        cout<<array[i]<<" ";
129 //    }
130 //    delete hs;
131
132
133 //    LinkedHashTable *hs=new LinkedHashTable(11,12);
134 //    int a[]={37,25,14,36,49,68,57,11};
135 //    for(int i=0;i<8;i++)
136 //        hs->insert(a[i]);
137 //    Node **array=hs->getArray();
138 //    for(int i=0;i<12;i++){
139 //        Node *p=array[i]->next;
140 //        while(p!=NULL){
141 //            cout<<p->data<<" ";
142 //            p=p->next;
143 //        }
144 //        cout<<endl;
145 //    }
146 //    delete hs;
147     return 0;
148 }

  

时间: 2024-08-04 22:33:35

散列(C++实现)的相关文章

【数据结构】之散列链表(Java语言描述)

散列链表,在JDK中的API实现是 HashMap 类. 为什么HashMap被称为"散列链表"?这与HashMap的内部存储结构有关.下面将根据源码进行分析. 首先要说的是,HashMap中维护着的是一个数组: transient Node<K,V>[] table; ,数组中的每个元素都是一个 Node 对象.这里的Node是HashMap的一个内部类,代码如下: static class Node<K,V> implements Map.Entry<

Redis常用命令(一) 字符串键、散列键

redis是key-value的数据结构,每条数据都是一个键值对 键的类型是字符串,因为默认是字符串所以都不用加引号 注意:键不能重复 值的类型分为五种: 字符串string 散列hash 列表list 集合set 有序集合zset string字符串键 set key value  # 设置的键不存在则为添加,如果设置的键已经存在则修改 set name daiby set key value [NX|XX]  # NX: 如果key不存在则成功,反之失败(不覆盖旧值)! XX: 如果key存

散列、加密、编码 漫谈

散列(又叫Hash)和加密在身份校验.敏感信息传输等应用中用途广泛. 把他们放在一起写的原因是,网上太多资料,将散列和加密的概念混为一谈,误导性极大. 由于编码/解码运算和上述二者有一定的相似之处,因此放在这里一并讲述. 注:本文中,为了表述严谨,所有的"位"代表的是字符个数之意,而bit则指代计算机数据中的基本单位比特. 1.三者的共同点 它们都表述了一种映射关系,将原始数据A映射到新的数据B. 在散列运算中,B一般称之为摘要,英文为digest. 其代表算法有MD5,SHA1, S

栈,散列映射

栈的方法 public void push(E item) public E pop() public boolean empty() public E peek()//获得栈顶数据 public int search(Oject data)//查找栈是否有data项,没有返回-1 HashMap散列映射 HashMap<String,V> 方法 public void put(Key k,Value v)//加入 public void clear()//清空散列映射 public bool

数据库表散列

http://dapple.iteye.com/blog/740338 数据库表散列: 思路:1.缩短查询耗时: 2.分拆表或者库,表小,查询自然快: 3.需要快速定位,hash算法可以做到这种(唯一)映射

散列之HashTable学习

1,什么是散列? 举个例子,在日常生活中,你将日常用品都放在固定的位置,当你下次需要该东西时,直接去该地方取它.这个过程就相当于散列查找. 若将它们随意杂乱无章地存放,当需要某件东西时,只能一个地方一个地方地逐一查找,这就相当于顺序查找. 在数据结构中,数组就相当于一张散列表,因为可以根据数组下标索引直接取得该位置上的元素. 2,什么情况下用到散列? 由于散列查找相对于其它查找而言,理论上只需要O(1)时间就可以找到某元素,因此,当查找是主要的任务时,散列就是实现词典的一种很好的选择. 3,散列

.Net加密与解密——散列运算

一,散列运算的特点 1,散列运算是不可逆的,可以将散列运算理解为单向的加密: 2,任何两个不相同的文件,哪怕只有一个字节的细微差别,得到的摘要都是完全不同的.这个特点的意义在于,可以用来判断消息是否被篡改,即解决完整性的问题. 3,无论原始消息的大小如何,运算得出的摘要的信息是固定长度,摘要的长度根据散列算法的不同而不同. 二,利用散列运算判断消息是否被篡改的流程 1,发送放对消息进行散列运算,得到消息摘要,发送消息和摘要,并说明获得摘要所使用的散列算法. 2,接收方获得消息和原始摘要,使用相同

c语言 &lt;除法散列法&gt; 高效 HashTable Dictionary

c语言 <除法散列法> 高效 HashTable Dictionary  ,不管集合大小,任意长度根据key查询都只是一次寻址左右,so 最快时间复杂度为O1! 先上代码,明天写原理注释! HashDictionary.h #define CM_STR_HASHFUNC_CONSTANT 31 #define KEYSIZE 40 struct Entry { int hashCode; int next; char key[KEYSIZE]; void* value; }; struct H

没事写个散列玩~

感觉散列的查找性能真心不错,如果使用普通线性结构查找,平均时间是n/2.而刚才用实验,256大小的散列,存储128个数据,平均时间为2次以内.感觉真心NB 1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <cstdlib> 5 #include <ctime> 6 7 using namespace std; 8 typedef bool BOOL;