求链地址法的实现(数据结构之查找)
数据结构之查找处理数据冲突的方法,链地址法。
麻烦大家帮帮忙啊!贴出自己错误的代码。希望高手们改改,或者说说你们的想法。
#include<iostream>
#include<stdlib.h>
#include<math.h>
using namespace std;
typedef struct list
{
int value;
list *next;
}link, *node;
const int hash_max=10;
const int array_max=15;
void create(int);
void print(int);
node index_hash[hash_max];
node free_node; //释放指向的内存
node temp;
node contact;
void main()
{
int i,data[array_max];
for(i=0;i<array_max;i++)
{
data[i]=rand()%200;
}
cout<<"产生的数据为"<<endl;
for(i=0;i<array_max;i++)
{
cout<<data[i]<<" ";
}
cout<<endl;
cout<<"建立哈希表中......"<<endl;
for(i=0;i<array_max;i++)
{
create(data[i]);
}
cout<<"输出哈希表"<<endl;
for(i=0;i<hash_max;i++)
{
print(i);
}
}
void create(int val)
{
int hash=val%hash_max;
temp=contact; //保存前一个结点
node new_node=new list;
if(new_node==NULL)
{
cout<<"内存申请不成功!"<<endl;
exit(1);
}
new_node->value=val;
new_node->next=NULL;
contact=new_node;
if(temp!=NULL &&temp->value%hash_max==contact->value%hash_max) //这里建立链表是否正确的?
{
temp->next=contact;
}
index_hash[hash]=contact;//如何在这(函数里)维持一个指向头结点的指针?我这样每次都指向最后一个冲突数据。
}
void print(int val)
{
node show;
int count=0;
show=index_hash[val];
cout<<val<<'\t';
while(show)
{
free_node=show;
cout<<show->value<<"-";
show=show->next;
delete free_node;
free_node=NULL;
}
cout<<"\b "<<endl;
}
希望大家帮帮忙,感激不尽!
[解决办法]
- C/C++ code
#include<iostream>#include<assert.h>#include<math.h>#include<time.h>using namespace std;typedef int KeyType;typedef int OtherInfoType;struct ElemNode{KeyType Key; // 关键字 ElemNode *next;};struct HeadNode{ElemNode *next;};class cep{protected:HeadNode *ht; // 散列表结头,存放的是指针而非具体的地址,只是提供一个索引而已int p; // 除留余法的除数,可以作为是头结点指针索引的数量int H(KeyType Key); // 散列函数,just it is ok otheres didn't have any addpublic:cep(int divisor=0); ~cep();void Clear();void Traverse(void (*Vist)(ElemNode *&));bool Search(const KeyType &Key,ElemNode *&Pre,ElemNode *&Me); // 查找关键字为Key的地址,the most important functionbool Insert(const KeyType &Key);bool Delete(const KeyType &Key);cep(const cep ©);cep & operator=(const cep ©);};int cep::H(KeyType Key){return Key%p;}cep::cep(int divisor){assert(divisor>=0); p=divisor;ht=new HeadNode[p]; // 也是以其为结点数分配的,很是聪明for(int i=0;i<p;i++){ ht[i].next=NULL; // very clever,just to do it}}cep::~cep(){Clear();}void cep::Clear(){ElemNode *w,*q;for(int i=0;i<p;i++){ w=ht[i].next; while(w) { q=w; delete w; w=q->next; }}delete []ht; // 释放指针索引结点}void cep::Traverse(void (*Vist)(ElemNode *&)) // *& 指针引用{int i;ElemNode *temp;for(i=0;i<p;i++){ cout<<i<<":"; temp=ht[i].next; while(temp) { (*Vist)(temp); temp=temp->next; } cout<<endl;}}bool cep::Search(const KeyType &Key,ElemNode *&Pre,ElemNode *&Me) // 只能查找第一个出现之地,而不能反应全部{int pos;pos=H(Key);Pre=NULL;Me=ht[Key].next; // 最要提防的是Me==ht[Key].nextif(Me->Key==Key){ return true;}while(Me!=NULL){ Pre=Me; Me=Me->next; if(Me->Key==Key) break;}if(Me!=NULL) return true;else return false;}bool cep::Insert(const KeyType &Key){int pos;pos=H(Key);ElemNode *temp;temp=new ElemNode;temp->Key=Key;temp->next=ht[pos].next; // 在此就显示出了人工自动赋值的重要性 ht[pos].next=temp;return true;}bool cep::Delete(const KeyType &Key) // 值可能会出现重复想象,所以必须扫描完全方可结束,最好不要用Seaerch{int flag=0;ElemNode *Pre,*Me;if(Search(Key,Pre,Me)) // 查找成功,继续向下探索{ Pre->next=Me->next; delete Me; flag=1;} // 之后从Pre->next 又开始继续查找if(flag==1){ while(Search(Key,Pre,Me)) { Pre->next=Me->next; delete Me; } return true;}else return false;}cep::cep(const cep ©) // 此谁及链表的复制,所以必须格外小心,不能指向同一个内存单元否则出错{int i;ElemNode *temp1,*temp2,*Pre;p=copy.p;ht=new HeadNode[p]; for(i=0;i<p;i++) // 如何设计看我本人,我思故我在{ temp1=copy.ht[i].next; if(temp1==NULL) { ht[i].next=NULL; } else { temp2=new ElemNode; temp2->Key=temp1->Key; temp2->next=NULL; ht[i].next=temp2; // 处理第一个结点,接下来在处理其他 temp1=temp1->next; while(temp1!=NULL) { Pre=temp2; temp2=new ElemNode; temp2->Key=temp1->Key; temp2->next=NULL; Pre->next=temp2; temp1=temp1->next; } }}}cep & cep::operator =(const cep ©){if(©!=this){ Clear(); int i; ElemNode *temp1,*temp2,*Pre; p=copy.p; ht=new HeadNode[p]; for(i=0;i<p;i++) // 如何设计看我本人,我思故我在 { temp1=copy.ht[i].next; if(temp1==NULL) { ht[i].next=NULL; } else { temp2=new ElemNode; temp2->Key=temp1->Key; temp2->next=NULL; ht[i].next=temp2; // 处理第一个结点,接下来在处理其他 temp1=temp1->next; while(temp1!=NULL) { Pre=temp2; temp2=new ElemNode; temp2->Key=temp1->Key; temp2->next=NULL; Pre->next=temp2; temp1=temp1->next; } } }}return *this;}void Vist(ElemNode *&elem){cout<<elem->Key<<" ";}int main(void){KeyType Key;cep A(10);srand(time(NULL));for(int i=0;i<10;i++){ Key=rand()%100; cout<<Key<<endl; A.Insert(Key);}A.Traverse(Vist);cep B(A);cout<<"==================="<<endl;B.Traverse(Vist);cout<<"==================="<<endl;cep C;C=B;C.Traverse(Vist);system("PAUSE");return 0;}