hashmap c
問題提出:
假如一個結構體,記錄有學號,姓名。現在內存塊中存在著一批此類結構體。如果已知一個學號,要從這些結構體中找出對應的姓名。
問題解決方法:
如果使用鏈表保存這些結構體,就要遍歷這個鏈表中的結構體,比較每個結構體的學號成員,如果相等就返回這個結構體,從而得到結構體的姓名成員。
但是遍歷效率太低,浪費cpu,有點費電。不如使用hash表直接定位到對應的結構體,而不必遍歷。
具體做法見代碼。說明如下
1.hash表的構建:除留余數法。
2,沖突處理:開放定址法。如果把hash表大小和元素個數定成一樣大小,則一點也不浪費空間。
3.如果預先不知道數組的大小,那幾個全局數組可以使用vector代替。
4.這是手工實現的hash表創建,沖突處理。也可以使用boost庫的hashmap.待續
the code refer to c/c++ 函數與算法速查手冊 陳銳
// hash1.cpp : 定義控制臺應用程序的入口點。#include "stdafx.h" #include<stdio.h> #include<malloc.h> #include<stdlib.h> #include <string> typedef struct /*元素類型定義*/ {int value; /*元素值,學號*/int hi; /*沖突次數*/char name[20];char sex; }DataType; typedef struct /*哈希表類型定義*/ {DataType *data;int length; /*哈希表的長度*/int num; /*表中元素個數*/ }HashTable; void CreateHashTable(HashTable *H,int m,int n); int SearchHash(HashTable H,int k); void HashASL(HashTable H,int m); void DisplayHash(HashTable H,int m);int num[]= {8923, 90, 66, 70, 155, 2456, 123, 987}; char* name[]={"song","rui","lili","mme","feng","ann","tom","min"}; char sex[]={1,2,3,4,5,6,7,8};int m_TotalLen=99999; int m_CurLen=8; int _tmain(int argc, _TCHAR* argv[]) {HashTable H;int pos,v;CreateHashTable(&H,m_TotalLen,m_CurLen);DisplayHash(H,m_TotalLen);while (1){printf("請輸入待查找學生的學號:");scanf("%d",&v);pos=SearchHash(H,v);if (pos==-1) continue;printf("學號%d在哈希表中的位置:%d,姓名:%s \n",v,pos,H.data[pos].name);HashASL(H,m_TotalLen);}} void CreateHashTable(HashTable *H,int m,int n) /*構造哈希表,并處理沖突*/ { int i,sum,addr,di;/*為哈希表分配存儲空間*/(*H).data=(DataType*)malloc(m*sizeof(DataType));if(!(*H).data) exit(-1); (*H).num=n; /*初始化哈希表的元素個數*/(*H).length=m; /*初始化哈希表的長度*/for(i=0;i<m;i++) /*初始化哈希表*/{(*H).data[i].value=-1;(*H).data[i].hi=0;(*H).data[i].sex=0;}/*構造哈希表并處理沖突*/for(i=0;i<n;i++){sum=0; /*sum記錄沖突次數*/addr=num[i]%m; /*利用除留余數法求哈希函數地址*/di=addr;if((*H).data[addr].value==-1) /*如果不沖突則將元素存儲在表中*/{(*H).data[addr].value=num[i];(*H).data[addr].hi=1;strcpy((*H).data[addr].name,name[i]);(*H).data[addr].sex=sex[i];}else /*用線性探測再散列法處理沖突*/{do {di=(di+1)%m;sum+=1;} while((*H).data[di].value!=-1);(*H).data[di].value=num[i];(*H).data[di].hi=sum+1;strcpy((*H).data[di].name,name[i]);(*H).data[di].sex=sex[i];}} } int SearchHash(HashTable H,int v) /*在哈希表H中查找值為v的元素*/ {int d,d1,m;m=H.length;d=d1=v%m; /*求v的哈希地址*/while(H.data[d].value!=-1){if(H.data[d].value==v) /*如果找到要查找的元素v,則返回v的位置*/return d;else /*如果不是要找的元素,則繼續向后查找*/d=(d+1)%m;if(d==d1) /*如果找遍了哈希表中的所有位置還沒有找到v,則返回0*/return -1;}return -1; /*該位置不存在元素v*/ } void HashASL(HashTable H,int m) /*求哈希表的平均查找長度*/ {float average=0;int i;for(i=0;i<m;i++)average=average+H.data[i].hi;average=average/H.num;printf("平均查找長度ASL:%.2f",average);printf("\n"); } void DisplayHash(HashTable H,int m) /*輸出哈希表*/ {int i;printf("哈希表地址: ");for(i=0;i<m;i++) /*輸出哈希表的地址*/printf("%-5d",i);printf("\n");printf("元素值value: ");for(i=0;i<m;i++) /*輸出哈希表的元素值*/printf("%-5d",H.data[i].value);printf("\n");printf("沖突次數: ");for(i=0;i<m;i++) /*沖突次數*/printf("%-5d",H.data[i].hi);printf("\n");printf("性別: ");for(i=0;i<m;i++) printf("%-5d",H.data[i].sex);printf("\n");printf("name: ");for(i=0;i<m;i++) printf("%s ",H.data[i].name);printf("\n"); }
假如一個結構體,記錄有學號,姓名。現在內存塊中存在著一批此類結構體。如果已知一個學號,要從這些結構體中找出對應的姓名。
問題解決方法:
如果使用鏈表保存這些結構體,就要遍歷這個鏈表中的結構體,比較每個結構體的學號成員,如果相等就返回這個結構體,從而得到結構體的姓名成員。
但是遍歷效率太低,浪費cpu,有點費電。不如使用hash表直接定位到對應的結構體,而不必遍歷。
具體做法見代碼。說明如下
1.hash表的構建:除留余數法。
2,沖突處理:開放定址法。如果把hash表大小和元素個數定成一樣大小,則一點也不浪費空間。
3.如果預先不知道數組的大小,那幾個全局數組可以使用vector代替。
4.這是手工實現的hash表創建,沖突處理。也可以使用boost庫的hashmap.待續
the code refer to c/c++ 函數與算法速查手冊 陳銳
// hash1.cpp : 定義控制臺應用程序的入口點。#include "stdafx.h" #include<stdio.h> #include<malloc.h> #include<stdlib.h> #include <string> typedef struct /*元素類型定義*/ {int value; /*元素值,學號*/int hi; /*沖突次數*/char name[20];char sex; }DataType; typedef struct /*哈希表類型定義*/ {DataType *data;int length; /*哈希表的長度*/int num; /*表中元素個數*/ }HashTable; void CreateHashTable(HashTable *H,int m,int n); int SearchHash(HashTable H,int k); void HashASL(HashTable H,int m); void DisplayHash(HashTable H,int m);int num[]= {8923, 90, 66, 70, 155, 2456, 123, 987}; char* name[]={"song","rui","lili","mme","feng","ann","tom","min"}; char sex[]={1,2,3,4,5,6,7,8};int m_TotalLen=99999; int m_CurLen=8; int _tmain(int argc, _TCHAR* argv[]) {HashTable H;int pos,v;CreateHashTable(&H,m_TotalLen,m_CurLen);DisplayHash(H,m_TotalLen);while (1){printf("請輸入待查找學生的學號:");scanf("%d",&v);pos=SearchHash(H,v);if (pos==-1) continue;printf("學號%d在哈希表中的位置:%d,姓名:%s \n",v,pos,H.data[pos].name);HashASL(H,m_TotalLen);}} void CreateHashTable(HashTable *H,int m,int n) /*構造哈希表,并處理沖突*/ { int i,sum,addr,di;/*為哈希表分配存儲空間*/(*H).data=(DataType*)malloc(m*sizeof(DataType));if(!(*H).data) exit(-1); (*H).num=n; /*初始化哈希表的元素個數*/(*H).length=m; /*初始化哈希表的長度*/for(i=0;i<m;i++) /*初始化哈希表*/{(*H).data[i].value=-1;(*H).data[i].hi=0;(*H).data[i].sex=0;}/*構造哈希表并處理沖突*/for(i=0;i<n;i++){sum=0; /*sum記錄沖突次數*/addr=num[i]%m; /*利用除留余數法求哈希函數地址*/di=addr;if((*H).data[addr].value==-1) /*如果不沖突則將元素存儲在表中*/{(*H).data[addr].value=num[i];(*H).data[addr].hi=1;strcpy((*H).data[addr].name,name[i]);(*H).data[addr].sex=sex[i];}else /*用線性探測再散列法處理沖突*/{do {di=(di+1)%m;sum+=1;} while((*H).data[di].value!=-1);(*H).data[di].value=num[i];(*H).data[di].hi=sum+1;strcpy((*H).data[di].name,name[i]);(*H).data[di].sex=sex[i];}} } int SearchHash(HashTable H,int v) /*在哈希表H中查找值為v的元素*/ {int d,d1,m;m=H.length;d=d1=v%m; /*求v的哈希地址*/while(H.data[d].value!=-1){if(H.data[d].value==v) /*如果找到要查找的元素v,則返回v的位置*/return d;else /*如果不是要找的元素,則繼續向后查找*/d=(d+1)%m;if(d==d1) /*如果找遍了哈希表中的所有位置還沒有找到v,則返回0*/return -1;}return -1; /*該位置不存在元素v*/ } void HashASL(HashTable H,int m) /*求哈希表的平均查找長度*/ {float average=0;int i;for(i=0;i<m;i++)average=average+H.data[i].hi;average=average/H.num;printf("平均查找長度ASL:%.2f",average);printf("\n"); } void DisplayHash(HashTable H,int m) /*輸出哈希表*/ {int i;printf("哈希表地址: ");for(i=0;i<m;i++) /*輸出哈希表的地址*/printf("%-5d",i);printf("\n");printf("元素值value: ");for(i=0;i<m;i++) /*輸出哈希表的元素值*/printf("%-5d",H.data[i].value);printf("\n");printf("沖突次數: ");for(i=0;i<m;i++) /*沖突次數*/printf("%-5d",H.data[i].hi);printf("\n");printf("性別: ");for(i=0;i<m;i++) printf("%-5d",H.data[i].sex);printf("\n");printf("name: ");for(i=0;i<m;i++) printf("%s ",H.data[i].name);printf("\n"); }
轉載于:https://www.cnblogs.com/-song/archive/2012/10/20/3331842.html
總結
- 上一篇: CSS3--transition
- 下一篇: CMS之图片管理(2)