散列表(哈希表)是根据关键字直接访问内存存储位置的数据结构,仅支持插入、查找、删除操作。在最坏情况下,查找一个元素的时间为Θ(n),而在一些合理的假设下,查找一个元素的期望时间为O(1)。
散列表是普通数组的推广。对于普通数组:
1、我们可以将关键字为k的元素存到数组下标为k的位置里。
2、如果有一个关键字k,我们直接查看数组下标为k的位置。
这种方式为直接寻址方式。但是这种方式有不足:只适用于关键字的全域比较小,而且没有两个元素的关键字完全相同。而显示中存储的关键字集合会比关键字的全域相对小很多。
下图为直接寻址表:
代码实现如下:(刚开始打算直接开个装元素的数组,慢慢发现删除的时候有点麻烦,所以改为指针数组,方便删除后直接指向NULL指针)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define MAX 6 5 6 typedef struct { 7 int key; 8 int satellite; 9 }Data; //元素结构体,有关键字和卫星数据 10 11 Data* direct_address_search(Data *T[], int key); //散列表查找操作 12 13 void direct_address_insert(Data *T[], Data *x); //散列表插入操作 14 15 void direct_address_delete(Data *T[], Data *x); //散列表删除操作 16 17 void print_table(Data *T[]); //打印散列表(为了方便查看删除操作后,散列表的变化) 18 19 int main(){ 20 int i, num, key, satellite; 21 Data *data[MAX]; 22 Data *d; 23 for(i = 0; i < MAX; i++){ 24 data[i] = (Data *)malloc(sizeof(Data)); 25 data[i] = NULL; 26 } 27 28 for(i = 0; i <= 3; i++){ 29 d = (Data *)malloc(sizeof(Data)); 30 printf("Input the key_value:\n"); 31 scanf("%d", &key); 32 printf("Input the satellite:\n"); 33 scanf("%d", &satellite); 34 d->key = key; 35 d->satellite = satellite; 36 direct_address_insert(data, d); 37 } 38 print_table(data); 39 key = 3; 40 d = direct_address_search(data, key); 41 printf("the key is %d, and its satellite is %d\n", d->key, d->satellite); 42 43 direct_address_delete(data, d); 44 print_table(data); 45 free(d); 46 for(i = 0; i < MAX; i++) 47 free(data[i]); 48 return 0; 49 } 50 51 /* 52 *直接返回下标为key的元素 53 */ 54 Data* direct_address_search(Data *T[], int key){ 55 return T[key]; 56 } 57 58 /* 59 * 直接将元素插入下标key的位置里 60 */ 61 void direct_address_insert(Data *T[], Data *x){ 62 T[x->key] = x; 63 } 64 65 /* 66 * 将要删除的元素所在的位置指向空指针 67 */ 68 void direct_address_delete(Data *T[], Data *x){ 69 T[x->key] = NULL; 70 } 71 72 /* 73 * 打印直接寻址表 74 */ 75 void print_table(Data *T[]){ 76 int i; 77 for(i = 0; i < MAX; i++){ 78 if(T[i] != NULL){ 79 printf("key is %d, and its satellite is %d\n", T[i]->key, T[i]->satellite); 80 } 81 } 82 }