C里面怎样定义hash表啊?

kiono 2008-07-31 01:57:49
我现在要定义一个User的hash表,把它放到hash表里面,userid作为Key,Vlue是userName,userPhone,userCert的集合或者struct,看怎样实现方便,C我不熟悉,所以请教一下大家。请大家教我一下,完整的构建这个hashTable的完整代码,谢谢了。
...全文
457 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjlsmail 2009-10-13
  • 打赏
  • 举报
回复
Mark
yyyapple 2008-08-01
  • 打赏
  • 举报
回复
抽点空,改了一下, 在vs2005下编译的
.h

/* HASH.H
**
** Header file for Hash Table module HASH.C
**
*/
#ifndef __HASH_H
#define __HASH_H

#define HTMAXSIZE 1999
#define NOTFOUND 0
#define MAXLEN 127
#ifdef __cplusplus
extern "C" {
#endif

struct HTdata //用户数据
{
char *key;
char *userName;
char *userPhone;
char *userCert;
};

typedef struct HTdata *HTelem;

struct HTentry //hash table 结构
{
HTelem elem;
struct HTentry *next;
};


typedef struct HTentry *HTtable;

HTtable *HTcreate(void); //创建hash table
int HTinsert(HTtable *, char*, HTelem ); //根据用户提供的关键字和数据插入表格中
HTelem HTfind(HTtable *, char * ); //根据关键字,查找数据
void HTfree(HTtable *); //释放hash table


#ifdef __cplusplus
}
#endif

#endif


.c
/* HASH.C
**
** Implementation of a simple Hash Table for string storage & retrieval
**
** Written by L. Rossman
**
** The hash table data structure (HTable) is defined in "hash.h".
** Interface Functions:
** HTcreate() - creates a hash table
** HTinsert() - inserts a string & its index value into a hash table
** HTfind() - retrieves the index value of a string from a table
** HTfree() - frees a hash table
**
*/

#include <malloc.h>
#include <string.h>
#include "hash.h"

int hash(char *key) //hash索引值算法
{
int n = 0;
char *ch = key;
while (*ch)
{
n <<= 1;
n += (*ch);
++ch;
}
return(n % HTMAXSIZE);
}

HTtable *HTcreate() //创建hash table
{
int i;
HTtable *ht =
(HTtable *) calloc(HTMAXSIZE, sizeof(HTtable));
if (ht != NULL)
for (i=0; i<HTMAXSIZE; i++) ht[i] = NULL;
return(ht);
}

int HTinsert(HTtable *ht, char* key, HTelem elem) //数据插入hash table,成功返回1,失败返回0
{
int i = hash(key);
struct HTentry *entry;
if ((i < 0) || (i >= HTMAXSIZE) || (0==elem) ) return(0);
entry = (struct HTentry *) malloc(sizeof(struct HTentry));
if (entry == NULL) return(0);
elem->key = key;
entry->elem = elem;
entry->next = ht[i];
ht[i] = entry;
return(1);
}

HTelem HTfind(HTtable *ht, char* key) //根据关键字查找用户数据,找到返回用户数据指针,否则返回空
{
int i = hash(key);
struct HTentry *entry;
if ((i < 0) || (i >= HTMAXSIZE)) return(NOTFOUND);
entry = ht[i];
while (entry != NULL)
{
if (strcmp(entry->elem->key, key) == 0) return(entry->elem);
entry = entry->next;
}
return(NOTFOUND);
}

void HTfree(HTtable *ht) //清空hash table
{
struct HTentry *entry,
*nextentry;
int i;
for (i=0; i<HTMAXSIZE; i++)
{
entry = ht[i];
while (entry != NULL)
{
nextentry = entry->next;
free(entry);
entry = nextentry;
}
}
free(ht);
}


.c 测试主程序

#include "stdio.h"
#include "hash.h"

int main()
{
struct HTdata data[] = {
{"1", "yyyapple", "777777", "1234567"},
{"2", "yyyapple2", "777777", "1234567"},
{"3", "yyyapple3", "777777", "1234567"}
};
HTtable* pt = HTcreate();

for(int i=0;i <3; i++)
{
HTinsert(pt, data[i].key, &data[i]);
}

HTelem p1 = HTfind(pt, "2");

printf("key = %s, userName = %s, userPhone = %s, userCert = %s\n",
p1->key, p1->userName, p1->userPhone, p1->userCert);

HTfree(pt);
return 0;
}


9527他大爷 2008-08-01
  • 打赏
  • 举报
回复
学习
kiono 2008-08-01
  • 打赏
  • 举报
回复
yyyapple 我也没办法啊,工作需要,我也痛苦,简单帮我注释一下吧。
yyyapple 2008-08-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 kiono 的回复:]
yyyapple,你发的看的不是很懂,能配上注释吗?像shailen126 那样。
能不能用我的User信息来举例啊?谢谢了~~~
[/Quote]

晕,建议你还是去看看什么叫hash table,不懂c怎么用啊
kiono 2008-08-01
  • 打赏
  • 举报
回复
yyyapple,你发的看的不是很懂,能配上注释吗?像shailen126 那样。
能不能用我的User信息来举例啊?谢谢了~~~
yyyapple 2008-08-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 kiono 的回复:]
yyyapple写的是C++的吧?因为C我一点都不熟悉,但是需要在Linux环境下编程,没办法,只能用C,怎样在C里定义一个HASHTABLE啊??
[/Quote]

给你个c的,自己再补充点吧
.h

/* HASH.H
**
** Header file for Hash Table module HASH.C
**
*/

#define HTMAXSIZE 1999
#define NOTFOUND 0

struct HTentry
{
char *key;
int data;
struct HTentry *next;
};

typedef struct HTentry *HTtable;

HTtable *HTcreate(void);
int HTinsert(HTtable *, char *, int);
int HTfind(HTtable *, char *);
void HTfree(HTtable *);


.c

/* HASH.C
**
** Implementation of a simple Hash Table for string storage & retrieval
**
** Written by L. Rossman
**
** The hash table data structure (HTable) is defined in "hash.h".
** Interface Functions:
** HTcreate() - creates a hash table
** HTinsert() - inserts a string & its index value into a hash table
** HTfind() - retrieves the index value of a string from a table
** HTfree() - frees a hash table
**
*/

#include <malloc.h>
#include <string.h>
#include "hash.h"

int hash(char *key)
{
int n = 0;
char *ch = key;
while (*ch)
{
n <<= 1;
n += (*ch);
++ch;
}
return(n % HTMAXSIZE);
}

HTtable *HTcreate()
{
int i;
HTtable *ht =
(HTtable *) calloc(HTMAXSIZE, sizeof(HTtable));
if (ht != NULL)
for (i=0; i<HTMAXSIZE; i++) ht[i] = NULL;
return(ht);
}

int HTinsert(HTtable *ht, char *key, int data)
{
int i = hash(key);
struct HTentry *entry;
if ((i < 0) || (i >= HTMAXSIZE)) return(0);
entry = (struct HTentry *) malloc(sizeof(struct HTentry));
if (entry == NULL) return(0);
entry->key = key;
entry->data = data;
entry->next = ht[i];
ht[i] = entry;
return(1);
}

int HTfind(HTtable *ht, char *key)
{
int i = hash(key);
struct HTentry *entry;
if ((i < 0) || (i >= HTMAXSIZE)) return(NOTFOUND);
entry = ht[i];
while (entry != NULL)
{
if (strcmp(entry->key,key) == 0) return(entry->data);
entry = entry->next;
}
return(NOTFOUND);
}

void HTfree(HTtable *ht)
{
struct HTentry *entry,
*nextentry;
int i;
for (i=0; i<HTMAXSIZE; i++)
{
entry = ht[i];
while (entry != NULL)
{
nextentry = entry->next;
free(entry);
entry = nextentry;
}
}
free(ht);
}


太乙 2008-08-01
  • 打赏
  • 举报
回复
嗯,自己定义,用着方便!
shailen126 2008-08-01
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <stdio.h>
#include <string.h>

typedef struct STUDENT //单元数组
{
char* name;
int score;
struct STUDENT* pnext;
}STUDENT;
STUDENT* Hashtab[100]; //HASH数组
void install(STUDENT* STR);
void CreateHashTab();
int HashNum(char* p);
void CreateHashTab() //每个单元赋值并插入HASH表
{
for (int i=0;i<100;i++)
{
STUDENT* str = new STUDENT;
str->name = new char(10);
sprintf(str->name,"Tom%d",i);
str->score = i;
str->pnext = NULL;
install(str);//插入HASH表
}

}
void install(STUDENT* STR)//插入HASH表
{
int h = HashNum(STR->name);
STR->pnext = Hashtab[h];
Hashtab[h] = STR;
}
int HashNum(char* p)//根据字符串计算HASH值
{
for (int i=0;*p;p++)
{
i = *p+31*i;
}
return i%100;
}

int main(int argc, char* argv[])
{
CreateHashTab();
printf("Hello World!\n");
return 0;
}
kiono 2008-08-01
  • 打赏
  • 举报
回复
yyyapple写的是C++的吧?因为C我一点都不熟悉,但是需要在Linux环境下编程,没办法,只能用C,怎样在C里定义一个HASHTABLE啊??
realdragon2 2008-08-01
  • 打赏
  • 举报
回复
HTtable * 是二级指针吧?
kiono 2008-08-01
  • 打赏
  • 举报
回复
yyyapple 兄,谢谢了,好人啊!!!
ack2me 2008-07-31
  • 打赏
  • 举报
回复
自己写,标准c没有提供类似c++的算法库,考验你数据结构基本功的时候到了。
  • 打赏
  • 举报
回复
up!~完整代码?????期待ing
yyyapple 2008-07-31
  • 打赏
  • 举报
回复
.h

/*
* Copyright (c) 1990, 1991 Stanford University
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Stanford not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Stanford makes no representations about
* the suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/*
* UHash - hash table.
*/

#ifndef unidraw_uhash_h
#define unidraw_uhash_h

#include <InterViews/defs.h>

class Iterator;
class UList;

class UHashElem {
public:
UHashElem(void* = nil);
virtual ~UHashElem();

void* GetKey();
void SetKey(void*);
private:
void* _key;
};

inline void* UHashElem::GetKey () { return _key; }
inline void UHashElem::SetKey (void* key) { _key = key; }

class UHashTable {
public:
UHashTable(int nslots);
virtual ~UHashTable();

virtual void Register(void* key, UHashElem* = nil);
virtual void Unregister(void* key);

void First(Iterator&);
void Next(Iterator&);
boolean Done(Iterator);

UHashElem* GetElem(Iterator);
UHashElem* Find(void* key);
protected:
virtual UHashElem* CreateElem();
virtual int Hash(void*);
protected:
int _nslots;
private:
UList* UElem(Iterator);
UHashElem* Elem(UList*);
void DeleteSlot(UList*);
private:
UList** _slot;
};

#endif


.c

/*
* Copyright (c) 1990, 1991 Stanford University
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Stanford not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Stanford makes no representations about
* the suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/*
* UHash implementation.
*/

#include <Unidraw/iterator.h>
#include <Unidraw/uhash.h>
#include <Unidraw/ulist.h>

#include <OS/memory.h>

/*****************************************************************************/

UHashElem::UHashElem (void* key) { _key = key; }
UHashElem::~UHashElem () { }

/*****************************************************************************/

UHashElem* UHashTable::CreateElem () { return nil; }
UHashElem* UHashTable::Elem (UList* r) { return (UHashElem*) (*r)(); }
int UHashTable::Hash (void* c) { return (unsigned) c % _nslots; }

UHashTable::UHashTable (int nslots) {
_nslots = nslots;
_slot = new UList*[_nslots];
Memory::zero(_slot, sizeof(void*) * _nslots);
}

UHashTable::~UHashTable () {
for (int i = 0; i < _nslots; ++i) {
if (_slot[i] != nil) {
DeleteSlot(_slot[i]);
}
}
delete _slot;
}

void UHashTable::Register (void* key, UHashElem* elem) {
int n = Hash(key);

if (_slot[n] == nil)
{
_slot[n] = new UList;
}
if (elem == nil) {
elem = CreateElem();
}
elem->SetKey(key);
_slot[n]->Prepend(new UList(elem));
}

void UHashTable::Unregister (void* key) {
int n = Hash(key);
UList* slot = _slot[n];

if (slot != nil) {
for (UList* u = slot->First(); u != slot->End(); u = u->Next()) {
UHashElem* elem = Elem(u);

if (elem->GetKey() == key) {
slot->Remove(u);
delete elem;
delete u;
break;
}
}
}
}

UList* UHashTable::UElem (Iterator i) { return (UList*) i.GetValue(); }
UHashElem* UHashTable::GetElem (Iterator i) { return Elem(UElem(i)); }

void UHashTable::First (Iterator& i) {
for (int j = 0; j < _nslots; ++j) {
if (_slot[j] != nil) {
i.SetValue(_slot[j]->First());
return;
}
}
i.SetValue(nil);
}

void UHashTable::Next (Iterator& i) {
UHashElem* elem = GetElem(i);

if (elem != nil) {
int n = Hash(elem->GetKey());
UList* u = UElem(i);
u = u->Next();

if (u == _slot[n]->End()) {
for (int j = n+1; j < _nslots; ++j) {
if (_slot[j] != nil) {
u = _slot[j]->First();
break;
}
}
}
i.SetValue(u);
}
}

boolean UHashTable::Done (Iterator i) {
for (int j = _nslots - 1; j >= 0; --j) {
if (_slot[j] != nil) {
return UElem(i) == _slot[j]->End();
}
}
return true;
}

UHashElem* UHashTable::Find (void* key) {
int n = Hash(key);
UList* slot = _slot[n];

if (slot != nil) {
for (UList* u = slot->First(); u != slot->End(); u = u->Next()) {
UHashElem* elem = Elem(u);

if (elem->GetKey() == key) {
return elem;
}
}
}
return nil;
}

void UHashTable::DeleteSlot (UList* slot) {
while (!slot->IsEmpty()) {
UList* u = slot->First();
slot->Remove(u);
UHashElem* elem = Elem(u);
delete elem;
delete u;
}
delete slot;
}

kiono 2008-07-31
  • 打赏
  • 举报
回复
是在C里面,不是C++
 本次课程会带着大家学习Hash算法,从源码的角度去学习算法,更加容易理解的方式去学习,能够更高效的吸收学到的内容,也能培养出能够独自看源码,分析源码的能力。Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。  哈希是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映射到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在中的存储位置,这种称为哈希或散列,所得存储位置称为哈希地址或散列地址。作为线性数据结构与格和队列等相比,哈希无疑是查找速度比较快的一种。  通过将单向数学函数(有时称为“哈希算法”)应用到任意数量的数据所得到的固定大小的结果。如果输入数据中有变化,则哈希也会发生变化。哈希可用于许多操作,包括身份验证和数字签名。也称为“消息摘要”。  简单解释:哈希(Hash)算法,即散列函数。它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧