在线等,菜鸟实现Hashtable时遇到的莫名其妙的问题……

mier0713 2011-03-03 04:43:09
还没有做完,但是基本框架都打好了。
key和value都是char*型,这是人家要求的……

问题是,在初始化hashtable时(main中调用InitHash(&ht)),是成功的。我给
char nullval='\0';
key=&char;

就是给key付了一个初值(我刚刚从java转c,神马都不懂,到底赋一个初始值是不是这样的也不知道--|||)
这时候打印*key是空格

但是到了InsertHash的时候,我先判断hashtable中有没有需要插入的key,所以调用了SearchHash方法,然后我发现
我的hashtable中的所有HashEle的*key的值都变了?(是不是变了到底)

#idefined NULLVAL '\0'
反正用*key==NULLVAL怎么都不相等,这样的话,系统就以为这个hashtable的所有key不为空,有值了,……于是怎么都插入不了

求解……orz

我在线等答案,好急……我也继续调……orz

源代码如下

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1 //插入时已存在
#define NULLKEY NULL


int htsize[]={19,31,81}; //处理冲突用 配置hashtable大小
int l;//哈希表当前表长

typedef struct{
char *key;
char *value;
}HashEle; //hash数据元素

typedef struct{
HashEle *elem; //HashEle数组
int count;
int index; // htsize[index]为当前容量
}HashTable;

//哈希函数 除留余数法
int Hash(char key){
return (key)/l;
}

//冲突处理,重置*p值
void Collision(int *p,int count){
*p=(*p+count)%l;
}
//初始化哈希表
int InitHash(HashTable *ht){
int i;
char nullval='\0';
(*ht).count=0;
(*ht).index=0;

l=htsize[(*ht).index];
(*ht).elem=(HashEle*)malloc(l*sizeof(HashEle));//分配初始空间;

if(!(*ht).elem)
return UNSUCCESS;
for(i=0;i<l;i++){
//赋初始值
(*ht).elem[i].key=&nullval;
printf("-%c-",*((*ht).elem[i].key));
}
return SUCCESS;
}
//重建哈希表
int RecreateHash(HashTable *ht){
printf("重建哈希表功能待编辑……");
return UNSUCCESS;
}
//注销哈希表并释放资源
void DestoryHash(HashTable *ht){
free((*ht).elem); //释放资源
(*ht).elem=NULL;
(*ht).count=0;
(*ht).index=0;
l=0;
}

int EQ(HashTable ht,int *p,char k);

//查找
int SearchHash(HashTable ht,char k,int *p,int *c){
*p=Hash(k);
printf("-%c-",*(ht.elem[*p].key));
while(*(ht.elem[*p].key)!=NULLKEY && !EQ(ht,p,k) && *c<l){
//取得下一冲突地址
Collision(p,*c);
(*c)++;
}
if(EQ(ht,p,k))
return SUCCESS;
return UNSUCCESS; //*p为下次可插入地址
}

//插入
int InsertHash(HashTable *ht,HashEle elem){
int c=0,p;
printf("insert:'%c'\n",*((*ht).elem[0].key));
if(SearchHash(*ht,*(elem.key),&p,&c))//如果该值已存在
return DUPLICATE;
else if(c>=htsize[(*ht).index]){//如果冲突次数达到上限
printf("size:%d",htsize[(*ht).index]);
RecreateHash(ht);
}
else{
(*ht).elem[p]=elem;
(*ht).count++;
return SUCCESS;
}
return UNSUCCESS;
}


/**
* 比较函数
* param:HashTable ht,int *p,char k
**/
int EQ(HashTable ht,int *p,char k){
printf("%d 比较值:ht-k -%c- k:-%c- \n",*p,*(ht.elem[*p].key),k);
//如果已存在
if(*(ht.elem[*p].key)==k)
return SUCCESS;

return UNSUCCESS;
}

void main(){
char c;
printf('%c',c);
int i,returnVal;
//初始化hashtable
HashTable ht;
if(InitHash(&ht))
printf("初始化hashtable成功!\n");

char k='a',v='b';
HashEle e={&k,&v};

returnVal=InsertHash(&ht,e);

printf("插入结果:%d",returnVal);

DestoryHash(&ht);
printf("注销hashtable!\n");
}
...全文
80 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
pengzhixi 2011-03-03
  • 打赏
  • 举报
回复
额 ,如果你非得指向一个值那就只能是静态或者全局变量了。
mier0713 2011-03-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pengzhixi 的回复:]
(*ht).elem[i].key=NULL;即可等你插入的时候你只需要判断(*ht).elem[i].key是否为NULL
[/Quote]
我测试了一下,改成NULL报错……内存溢出。
-----------所以我改成了-------
static char nullval=NULL;
----------人家告诉我的,其实也不是我改的哈哈-----------
不过原因和你说的一样
错误原因在于:
(*ht).elem[i].key=&nullval;
这句话,将局部变量的地址作为key的初值,局部变量销毁后,初值将变成随机值
mier0713 2011-03-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pengzhixi 的回复:]
(*ht).elem[i].key=NULL;即可等你插入的时候你只需要判断(*ht).elem[i].key是否为NULL
[/Quote]
啊啊,谢谢,我试一下~~❤
pengzhixi 2011-03-03
  • 打赏
  • 举报
回复
(*ht).elem[i].key=NULL;即可等你插入的时候你只需要判断(*ht).elem[i].key是否为NULL
pengzhixi 2011-03-03
  • 打赏
  • 举报
回复
(*ht).elem[i].key=&nullval;//因为nullval是一个局部变量当InitHash函数返回时这个变量被销毁了。
mier0713 2011-03-03
  • 打赏
  • 举报
回复
刚刚删除了一些不必要的代码:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1 //插入时已存在
#define NULLKEY NULL


int htsize[]={19,31,81}; //处理冲突用 配置hashtable大小
int l;//哈希表当前表长

typedef struct{
char *key;
char *value;
}HashEle; //hash数据元素

typedef struct{
HashEle *elem; //数组
int count;
int index; // htsize[index]为当前容量
}HashTable;

//哈希函数 除留余数法
int Hash(char key){
return (key)/l;
}

//冲突处理,重置*p值
void Collision(int *p,int count){
*p=(*p+count)%l;
}
//初始化哈希表
int InitHash(HashTable *ht){
int i;
char nullval='\0';
(*ht).count=0;
(*ht).index=0;

l=htsize[(*ht).index];
(*ht).elem=(HashEle*)malloc(l*sizeof(HashEle));//分配初始空间;

if(!(*ht).elem)
return UNSUCCESS;
for(i=0;i<l;i++){
//赋初始值
(*ht).elem[i].key=&nullval;
printf("-%c-",*((*ht).elem[i].key));
}
return SUCCESS;
}
//重建哈希表
int RecreateHash(HashTable *ht){
printf("因hashtable当前空间不足,重建哈希表,该功能待编辑……\n");
return UNSUCCESS;
}
//注销哈希表并释放资源
void DestoryHash(HashTable *ht){
free((*ht).elem); //释放资源
(*ht).elem=NULL;
(*ht).count=0;
(*ht).index=0;
l=0;
}

int EQ(HashTable ht,int *p,char k);

//查找
int SearchHash(HashTable ht,char k,int *p,int *c){
*p=Hash(k);
//printf("-%c-",*(ht.elem[*p].key));
while(*(ht.elem[*p].key)!=NULLKEY && !EQ(ht,p,k) && *c<l){
//取得下一冲突地址
Collision(p,*c);
(*c)++;
}
if(EQ(ht,p,k))
return SUCCESS;
return UNSUCCESS; //*p为下次可插入地址
}

//插入
int InsertHash(HashTable *ht,HashEle elem){
int c=0,p;
//printf("insert:'%c'\n",*((*ht).elem[0].key));
if(SearchHash(*ht,*(elem.key),&p,&c))//如果该值已存在
return DUPLICATE;
else if(c>=htsize[(*ht).index]){//如果冲突次数达到上限
//printf("size:%d",htsize[(*ht).index]);
RecreateHash(ht);
}
else{
(*ht).elem[p]=elem;
(*ht).count++;
return SUCCESS;
}
return UNSUCCESS;
}


/**
* 比较函数
* param:HashTable ht,int *p,char k
**/
int EQ(HashTable ht,int *p,char k){
//printf("%d 比较值:ht-k -%c- k:-%c- \n",*p,*(ht.elem[*p].key),k);
//如果已存在
if(*(ht.elem[*p].key)==k)
return SUCCESS;

return UNSUCCESS;
}

void main(){
int i,returnVal;
//初始化hashtable
HashTable ht;
if(InitHash(&ht))
printf("初始化hashtable成功!\n");

char k,v;
printf("输入两个字符作为key和value,用空格隔开后回车:\n");
scanf("%c %c",&k,&v);

HashEle e={&k,&v};

returnVal=InsertHash(&ht,e);

printf("插入结果:%d\n (0表示失败、1表示成功,-1表示已存在)\n",returnVal);

DestoryHash(&ht);
printf("注销hashtable!\n");
}

69,369

社区成员

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

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