新聞中心
哈希表設(shè)計(jì)的用Java代碼
#include stdio.h
創(chuàng)新互聯(lián)為企業(yè)級(jí)客戶提高一站式互聯(lián)網(wǎng)+設(shè)計(jì)服務(wù),主要包括網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站、重慶APP開發(fā)、微信小程序定制開發(fā)、宣傳片制作、LOGO設(shè)計(jì)等,幫助客戶快速提升營(yíng)銷能力和企業(yè)形象,創(chuàng)新互聯(lián)各部門都有經(jīng)驗(yàn)豐富的經(jīng)驗(yàn),可以確保每一個(gè)作品的質(zhì)量和創(chuàng)作周期,同時(shí)每年都有很多新員工加入,為我們帶來大量新的創(chuàng)意。
#include string.h
#include stdlib.h
//#include
#define HASH_LEN 50 //哈希表的長(zhǎng)度
#define M 47
#define NAME_NO 30 //人名的個(gè)數(shù)
typedef struct NAME
{
char *py; //名字的拼音
int k; //拼音所對(duì)應(yīng)的整數(shù)
}NAME;
NAME NameList[HASH_LEN];
typedef struct hterm //哈希表
{
char *py; //名字的拼音
int k; //拼音所對(duì)應(yīng)的整數(shù)
int si; //查找長(zhǎng)度
}HASH;
HASH HashList[HASH_LEN];
/*-----------------------姓名(結(jié)構(gòu)體數(shù)組)初始化---------------------------------*/
void InitNameList()
{
NameList[0].py="chenghongxiu";
NameList[1].py="yuanhao";
NameList[2].py="yangyang";
NameList[3].py="zhanghen";
NameList[4].py="chenghongxiu";
NameList[5].py="xiaokai";
NameList[6].py="liupeng";
NameList[7].py="shenyonghai";
NameList[8].py="chengdaoquan";
NameList[9].py="ludaoqing";
NameList[10].py="gongyunxiang";
NameList[11].py="sunzhenxing";
NameList[12].py="sunrongfei";
NameList[13].py="sunminglong";
NameList[14].py="zhanghao";
NameList[15].py="tianmiao";
NameList[16].py="yaojianzhong";
NameList[17].py="yaojianqing";
NameList[18].py="yaojianhua";
NameList[19].py="yaohaifeng";
NameList[20].py="chengyanhao";
NameList[21].py="yaoqiufeng";
NameList[22].py="qianpengcheng";
NameList[23].py="yaohaifeng";
NameList[24].py="bianyan";
NameList[25].py="linglei";
NameList[26].py="fuzhonghui";
NameList[27].py="huanhaiyan";
NameList[28].py="liudianqin";
NameList[29].py="wangbinnian";
char *f;
int r,s0;
for (int i=0;iNAME_NO;i++)
{
s0=0;
f=NameList[i].py;
for (r=0;*(f+r) != NULL;r++) //方法:將字符串的各個(gè)字符所對(duì)應(yīng)的ASCII碼相加,所得的整數(shù)做為哈希表的關(guān)鍵字
s0=*(f+r)+s0;
NameList[i].k=s0;
}
}
/*-----------------------建立哈希表---------------------------------*/
void CreateHashList()
{
for (int i=0; iNAME_NO; i ++)
{
HashList[i].py="";
HashList[i].k=0;
HashList[i].si=0;
}
for (i=0; i NAME_NO ; i++)
{
int sum=0;
int adr=(NameList[i].k) % M; //哈希函數(shù)
int d=adr;
if(HashList[adr].si==0) //如果不沖突
{
HashList[adr].k=NameList[i].k;
HashList[adr].py=NameList[i].py;
HashList[adr].si=1;
}
else //沖突
{
do{
d=(d+((NameList[i].k))%10+1)%M; //偽散列
sum=sum+1; //查找次數(shù)加1
}while (HashList[d].k!=0);
HashList[d].k=NameList[i].k;
HashList[d].py=NameList[i].py;
HashList[d].si=sum+1;
}
}
}
/*-------------------------------------查找------------------------------------*/
void FindList()
{
printf("\n\n請(qǐng)輸入姓名的拼音: "); //輸入姓名
char name[20]={0};
scanf("%s",name);
int s0=0;
for (int r=0;r20;r++) //求出姓名的拼音所對(duì)應(yīng)的整數(shù)(關(guān)鍵字)
s0+=name[r];
int sum=1;
int adr=s0 % M; //使用哈希函數(shù)
int d=adr;
if(HashList[adr].k==s0) //分3種情況進(jìn)行判斷
printf("\n姓名:%s 關(guān)鍵字:%d 查找長(zhǎng)度為: 1",HashList[d].py,s0);
else if (HashList[adr].k==0)
printf("無該記錄!");
else
{
int g=0;
do
{
d=(d+s0%10+1)%M; //偽散列
sum=sum+1;
if (HashList[d].k==0)
{
printf("無記錄! ");
g=1;
}
if (HashList[d].k==s0)
{
printf("\n姓名:%s 關(guān)鍵字:%d 查找長(zhǎng)度為:%d",HashList[d].py,s0,sum);
g=1;
}
}while(g==0);
}
}
/*--------------------------------顯示哈希表----------------------------*/
void Display()
{
printf("\n\n地址\t關(guān)鍵字\t\t搜索長(zhǎng)度\tH(key)\t\t拼音 \n"); //顯示的格式
for(int i=0; i15; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
printf("按任意鍵繼續(xù)顯示...\n"); //由于數(shù)據(jù)比較多,所以分屏顯示(以便在Win9x/DOS下能看到所有的數(shù)據(jù))
getchar();
for( i=15; i30; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
printf("按任意鍵繼續(xù)顯示...\n");
getchar();
for( i=30; i40; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
printf("按任意鍵繼續(xù)顯示...\n");
getchar();
for( i=40; i50; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
float average=0;
for (i=0;i NAME_NO;i ++)
average+=HashList[i].si;
average/=NAME_NO;
printf("\n\n平均查找長(zhǎng)度:ASL(%d)=%f \n\n",NAME_NO,average);
}
/*--------------------------------主函數(shù)----------------------------*/
void main()
{
/* ::SetConsoleTitle("哈希表操作"); //Windows API函數(shù),設(shè)置控制臺(tái)窗口的標(biāo)題
HANDLE hCon = ::GetStdHandle(STD_OUTPUT_HANDLE); //獲得標(biāo)準(zhǔn)輸出設(shè)備的句柄
::SetConsoleTextAttribute(hCon, 10|0); //設(shè)置文本顏色
*/
printf("\n------------------------哈希表的建立和查找----------------------");
InitNameList();
CreateHashList ();
while(1)
{
printf("\n\n");
printf(" 1. 顯示哈希表\n");
printf(" 2. 查找\n");
printf(" 3. 退出\n");
err:
char ch1=getchar();
if (ch1='1')
Display();
else if (ch1='2')
FindList();
else if (ch1='3')
return;
else
{
printf("\n請(qǐng)輸入正確的選擇!");
goto err;
}
}
}
java中的散列碼
首先,你要弄明白原因,你要明白兩點(diǎn):
1、你得有一定的匯編功底,了解堆和棧關(guān)系。
2、你得明白,java對(duì)像類和封裝類在內(nèi)存是怎么存儲(chǔ)的。
1首先解答為什么(a == b)-"不相等"
對(duì)像類和封裝類,在內(nèi)存中這樣存儲(chǔ)的:
a.當(dāng)new一個(gè)對(duì)像類時(shí),就會(huì)在堆中開辟一塊空間,然后,會(huì)把這個(gè)空間的地指向你new 的這個(gè)句柄,這個(gè)句柄就會(huì)放在棧中,(棧)就像個(gè)列表,CPU會(huì)向棧發(fā)送指令進(jìn)行操作。(棧像一本書的目錄,堆像書中的詳細(xì)章節(jié))棧中存放的對(duì)像的具體物理地址。
== :比的是棧中的東西,a棧的內(nèi)容是c8(散列碼是不分正負(fù)的,內(nèi)存表是1---11001000)
b棧的容易是c8(就是數(shù)字200的16進(jìn)制,內(nèi)存表是0---11001000)
因?yàn)椋?---11001000)?。剑?---11001000)所以在堆中要分兩段存儲(chǔ),比如堆地址為
00001000存放(1---11001000)為a,
堆地址為
00002000存放(0---11001000)為b,==比較的是00001000和00002000,所以不想等。
(String是比較特殊的對(duì)像,不是基本類型)
如果:String c = "abc";
String d = "abc";
它沒有new 在定義d = "abc";的時(shí)候,因?yàn)槎阎幸呀?jīng)有"abc"了就直接把它的地址負(fù)給了d,所以
c和d的棧中存儲(chǔ)的都是"abc"在堆中二進(jìn)制地址碼。所以不管是c==d還是c.equals(d)都是相等的。
equals:比較的是棧地址指向的堆中的內(nèi)容是否想等。針對(duì)所有對(duì)像都有效。
比較的是(1---11001000)和(0---11001000)所表示的內(nèi)容c8,所以想等。
這是有點(diǎn)不太好說清楚,不知道你明白了沒有。
java中如何獲取一個(gè)字符串的散列值?
String?str?=?"java";
System.out.println(str.hashCode());
輸出?3254818
JAVA中的散列表
散列表
(
Hash
table
,也叫
哈希表
),是根據(jù)關(guān)鍵碼值(Key
value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)。也就是說,它通過把關(guān)鍵碼值映射到表中一個(gè)位置來訪問記錄,以加快查找的速度。這個(gè)映射函數(shù)叫做散列函數(shù),存放記錄的數(shù)組叫做(
散列表).
hash
table
的概念??!
若結(jié)構(gòu)中存在關(guān)鍵字和K相等的記錄,則必定在f(K)的存儲(chǔ)位置上。由此,不需比較便可直接取得所查記錄。稱這個(gè)對(duì)應(yīng)關(guān)系f為散列函數(shù)(Hash
function),按這個(gè)思想建立的表為
散列表
。
對(duì)不同的關(guān)鍵字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),這種現(xiàn)象稱沖突。具有相同函數(shù)值的關(guān)鍵字對(duì)該散列函數(shù)來說稱做同義詞。綜上所述,根據(jù)散列函數(shù)H(key)和處理沖突的方法將一組關(guān)鍵字映象到一個(gè)有限的連續(xù)的地址集(區(qū)間)上,并以關(guān)鍵字在地址集中的“象”作為記錄在表中的存儲(chǔ)位置,這種表便稱為散列表,這一映象過程稱為散列造表或散列,所得的存儲(chǔ)位置稱散列地址。
若對(duì)于關(guān)鍵字集合中的任一個(gè)關(guān)鍵字,經(jīng)散列函數(shù)映象到地址集合中任何一個(gè)地址的概率是相等的,則稱此類散列函數(shù)為均勻散列函數(shù)(Uniform
Hash
function),這就是使關(guān)鍵字經(jīng)過散列函數(shù)得到一個(gè)“隨機(jī)的地址”,從而減少?zèng)_突。
散列函數(shù)能使對(duì)一個(gè)數(shù)據(jù)序列的訪問過程更加迅速有效,通過散列函數(shù),數(shù)據(jù)元素將被更快地定位
直接尋址法:取關(guān)鍵字或關(guān)鍵字的某個(gè)線性函數(shù)值為散列地址。即H(key)=key或H(key)
=
a·key
+
b,其中a和b為常數(shù)(這種散列函數(shù)叫做自身函數(shù))
數(shù)字分析法
平方取中法
折疊法
隨機(jī)數(shù)法
除留余數(shù)法:取關(guān)鍵字被某個(gè)不大于散列表表長(zhǎng)m的數(shù)p除后所得的余數(shù)為散列地址。即
H(key)
=
key
MOD
p,
p=m。不僅可以對(duì)關(guān)鍵字直接取模,也可在折疊、平方取中等運(yùn)算之后取模。對(duì)p的選擇很重要,一般取素?cái)?shù)或m,若p選的不好,容易產(chǎn)生同義詞。
關(guān)于解決沖突的方法
大概有4
種,
你GOOGLE
一下,
上面有寫的
,
在看下
JAVA
API
吧都有。。
Java相關(guān):什么是散列碼?
散列碼就是通過一種不可逆的散列(Hash)算法,對(duì)一個(gè)數(shù)據(jù)進(jìn)行計(jì)算,獲得一個(gè)“唯一”的值。這個(gè)值可以對(duì)這個(gè)數(shù)據(jù)進(jìn)行標(biāo)識(shí),在查找數(shù)據(jù)的時(shí)候,可以通過這個(gè)值來快速定位數(shù)據(jù),從而有效減少開銷。
由于散列長(zhǎng)度是有限和固定的,因此在數(shù)據(jù)極多的情況下散列值會(huì)出現(xiàn)重復(fù),用術(shù)語講就是“碰撞”。這個(gè)時(shí)候就需要其它方法來消除這種碰撞,比如再散列、拉鏈算法等。
舉個(gè)例子,設(shè)計(jì)一個(gè)散列算法,這個(gè)算法是把比劃數(shù)相加。
“知道”的散列值就是20,
“你好”的散列值就是13。(我數(shù)對(duì)沒有? :))
java 什么是散列碼
我的理解是:“散列碼”就是用來把一堆對(duì)象散到各自的隊(duì)列里去的一種標(biāo)識(shí)碼。
舉個(gè)形象一點(diǎn)的例子,一年有 365 天,從 1 編號(hào)到 365,下面我定義一種編碼方法,每個(gè)人按照他生日那天的編號(hào)作為他的標(biāo)識(shí)碼,這樣,一群人每個(gè)人就會(huì)有一個(gè)標(biāo)識(shí)碼。
這個(gè)標(biāo)識(shí)碼有什么用呢?好,下面我說,請(qǐng)所有單號(hào)的人站到一起,所有雙號(hào)的人站在一起。此后,當(dāng)我要找一個(gè)人的時(shí)候,如果知道他的編號(hào)是單號(hào),那我只需要到前面一堆人里去找,查找效率提高了一倍。
如果我說,請(qǐng)編號(hào)能被 16 整除的人站到一起,被 16 除余 1 的人站到一起,被 16 除余 2 的人站到一起…… 此后,當(dāng)我要找一個(gè)人的時(shí)候,查找效率就會(huì)提高到 16 倍。
這就是散列碼。所以,一個(gè)好的散列碼算法,配合一個(gè)適當(dāng)?shù)拇鎯?chǔ)機(jī)制,就能夠?qū)崿F(xiàn)高效的存儲(chǔ)管理。
那么,不好的散列碼算法會(huì)有多糟糕呢?比如,hashCode() 返回一個(gè)常量,那么,無論什么存儲(chǔ)機(jī)制都會(huì)退化,所有的人都站在一堆里,查找效率無法提高。不過,也就只是影響效率,不會(huì)影響“正確性”,因?yàn)樯⒘写a的本性決定了,所有的算法都不應(yīng)該假設(shè)兩個(gè)不同的對(duì)象必須有不同的散列碼。
分享標(biāo)題:散列查找java代碼 java散列表的應(yīng)用
網(wǎng)站鏈接:http://fisionsoft.com.cn/article/hpppeg.html