在C中打开哈希

时间:2014-01-12 16:09:10

标签: c dictionary hash

#define maxCells 1000
#define maxCS 11
#define maxIT 19

typedef struct
{
char LN[16], FN[24], MI;
}nametype;

typedef struct studtype
{
unsigned long ID;
nametype name;
char course[8];
int yr;
}student;

typedef struct ctype
{
student stud;
int next;
}celltype;

typedef struct
{
int *Header;
int CourseCtr;  /*holds the # of elements for each course*/
}CSIT;

typedef CSIT Dictionary[2];
typedef int LIST;

typedef struct
{
celltype heap[maxCells];
int AvailPtr;   /*holds the index to the first available cell in the VH*/
}*VirtualHeap;

问题定义:

BSCS和BSIT学生记录的列表存储在使用基于游标的实现表示的内部存储器中。该列表将被转换为字典,设置为ADT。使用开放散列(基于游标)在内存中表示字典。标题表中的每个组都按照ID进行升序排序。

*哈希函数存在,可以在函数中调用。该函数将接受一个元素作为其参数,并为每个元素返回适当的哈希值。

编写函数CreateDic()的代码 - 该函数将BSCS和BSIT学生记录的列表转换为字典,该字典将返回给调用函数。每个学生记录都由ID唯一标识。

问题

我不知道问题是什么,也不了解任何关于开放哈希的问题。我是这种语言的新手。这不是作业也不是练习。这是我们上周的考试,我从未理解过这个问题。谁能帮助我更好地理解这个问题。是否有代码。请帮我解决这个问题。

2 个答案:

答案 0 :(得分:2)

我感觉到你的痛苦。正如其他人所说,在这里可以做些什么来修补你的知识是有限的。以下是几点。

使用开放散列实现的集合是N个列表头指针(您的老师称为此数组Header)的数组,每个指针都是链接列表的开头。

要添加新元素,请创建并填写新的列表单元格,然后根据单元格的键计算整数哈希值H. (在您的问题中,使用学生ID本身作为哈希键可以正常工作。)将新单元格插入到链表中,头部指针位于索引(H mod N)。

现在,您的老师提供了一个框架,其中我上面提到的“指针”实现为整数数组索引。他或她使用顶部指针(整数索引)设置大量单元格,该指针始终显示单元格的分配方式。

这是一个非常传统的框架。没有多少生产系统会这样做。编码风格和数据结构选择相同,但让我们继续。

我们需要做出假设来完成问题:1)输入列表是“虚拟堆”的索引,2)我们应该销毁输入列表并重新使用节点插入哈希集。

考虑到所有这些,我们可以编写一些代码。

// Helper to create one CSIT hash set for the given list of students.
CSIT CreateCSITSet(size_t size, LIST lst, VirtualHeap *vh)
{
  CSIT csit;

  // Allocate the header array of integers and make them null.
  // safe_malloc is just malloc that exits properly if we're out of memory.
  csit.Header = safe_malloc(size * sizeof(int));

  // We're using -1 as a null index. 
  for (int i = 0; i < size; i++) csit.Header[i] = -1;

  // No students yet inserted.
  csit.CourseCtr = 0;

  // Traverse the input list and push onto the hash.
  int next = -1;
  for (int p = lst; p >= 0; p = next) {

    // Remember 'next' field because we'll change it below.
    next = vh.heap[p].next

    // Use the student ID to find the header index.
    int hix = vh.heap[p].stud.ID % size;

    // Push (and also unchain from the input list).
    vh.heap[p].next = csit.Header[hix];
    csit.Header[hix] = p;

    // Count the new entry.
    csit.CourseCtr++;
  }
  return csit;  // This returns the entire record: both fields.
}

// To create the dictionary, call our helper twice to fill in the hash sets.
Dictionary CreateDic(LIST bscs, LIST bsit, VirtualHeap *vh)
{
  Dictionary dict = safe_malloc(sizeof(Dictionary));
  dict[0] = CreateCSITSet(maxCS, bscs, vh);
  dict[1] = CreateCSITSet(maxIT, bsit, vh);
  return dict;
}

这显然是未经测试的,可能包含很小的错误,但它应该很接近。

请注意,我不满足哈希集内的列表应按排序顺序的要求。我会让你继续努力。

答案 1 :(得分:0)

这可能会为你提供一个良好的字典开头:

Quick Way to Implement Dictionary in C

如果您是C新手,您可能应该在进入开放哈希之前了解有关链接列表的更多信息。哈希表的条目将包含每个链接列表,或者至少包含它的头部。