seekg(A[d]*b2); f2.read((char*)&temp, b2); for(j=0; j if(temp.data[j].key==NullTag) break; if(j temp.data[j]=x; f2.seekg(-b2, ios::cur); f2.write((char*)&temp, b2); goto END; //插入表头结点后,转去做结束处理 }} //当d单链表为空或头结点中没有空闲位置时向下执行 //建立待插入d单链表表头的内存结点temp temp.data[0]=x; for(j=1; j temp.data[j].key=NullTag; temp.next=A[d]; //将temp结点的值写入到f2文件尾并被链接到d单链表的表头 if(A[m]==-1) { //将f2中的文件指针移至文件尾 f2.seekg(0,ios::end); //计算出文件尾的结点位置序号 int len=f2.tellg()/b2; //将temp结点的值写入文件尾 f2.write((char*)&temp,b2); //使A[d]指向新插入的结点 A[d]=len;} //将temp结点的值写入到f2文件的一个空闲结点中 //并被链接到d单链表的表头 else {//p指向空闲单链表的表头结点 int p=A[m]; //使空闲单链表的表头指针指向其下一个结点 f2.seekg(p*b2); FLNode pn; f2.read((char*)&pn, b2); A[m]=pn.next; //使temp的值写入到p位置的结点上 f2.seekg(-b2, ios::cur); f2.write((char*)&temp, b2); //使A[d]指向新插入的p结点 A[d]=p;} //将数组A中的全部内容写回到散列表文件f1中 f1.seekg(0); f1.write((char*)A, (m+1)*b1); //删除动态数组A和关闭所有文件 END: delete [] A; f1.close(); f2.close(); } //把数组x中n个元素插入到按桶散列的文件中 template void HFile::THFInsertB(char* fn1,char* fn2,T x[],int n) {fstream f1(fn1, ios::in|ios::out|ios::binary); if(!f1) {cerr< exit(1);} fstream f2(fn2, ios::in|ios::out|ios::binary); if(!f2) {cerr< exit(1);} int* A=new int[m+1]; if(!A) {cerr<<"申请堆内存失败!"< exit(1);} f1.read((char*)A, (m+1)*b1); for(int i=0; i {int d=x[i].key%m; int j; FLNode temp; if(A[d]!=-1) {f2.seekg(A[d]*b2); f2.read((char*)&temp, b2); for(j=0; j if(temp.data[j].key==NullTag) break; if(j temp.data[j]=x[i]; f2.seekg(-b2, ios::cur); f2.write((char*)&temp, b2); continue;}} temp.data[0]=x[i]; for(j=1;j temp.data[j].key=NullTag; temp.next=A[d]; if(A[m]==-1) { f2.seekg(0,ios::end); int len=f2.tellg()/b2; f2.write((char*)&temp,b2); A[d]=len;} else {int p=A[m]; f2.seekg(p*b2); FLNode pn; f2.read((char*)&pn, b2); A[m]=pn.next; f2.seekg(-b2, ios::cur); f2.write((char*)&temp, b2); A[d]=p;}} f1.seekg(0); f1.write((char*)A, (m+1)*b1); delete [] A; f1.close();f2.close(); } //从按桶散列的文件中删除关键字为x.key的元素,并由x带回该 //元素,若删除成功则返回1,否则返回0 template bool HFile::THFDelete(char* fn1,char* fn2,T& x) {fstream f1(fn1,ios::in|ios::out|ios::binary); int k; if(!f1) {cerr< exit(1);} fstream f2(fn2,ios::in|ios::out|ios::binary); if(!f2) {cerr< exit(1);} int* A=new int[m+1]; if(!A) {cerr<<"申请堆内存失败!"< exit(1);} f1.read((char*)A, (m+1)*b1); int DeleteTag=0; //用DeleteTag作为删除是否成功的标记 int d=x.key%m; int p=A[d],i=0; //用p保存d单链表的表头结点的位置序号, //用i保存该结点中被删除元素的下标或第一个空元素的下标 FLNode temp; //从d单链表的表头结点中删除关键字为x.key的元素 if(p!=-1) {f2.seekg(p*b2); f2.read((char*)&temp, b2); while(i if(temp.data[i].key==x.key) break; else i++; if(i x=temp.data[i]; //由x带回被删除的元素值 for(k=i+1; k if(temp.data[k].key!=NullTag) temp.data[k-1]=temp.data[k]; else break; temp.data[k-1].key=NullTag; if(k-1==0) { //删除d单链表中表头空结点 A[d]=temp.next; temp.next=A[m]; A[m]=p;} f2.seekg(-b2, ios::cur); f2.write((char*)&temp, b2); DeleteTag=1;// |