• 哈希表的实现(c语言)


    实现哈希表的方法有两种方法:开放寻址法 、链地址法

    • 开放寻址法:在开放寻址法中,所有的元素都存储在哈希表的数组中,冲突发生时会探测下一个可用的位置,直到找到一个空闲的位置。这种方法保持了元素的顺序,但可能导致聚集(clustering)。

    • 链地址法:链地址法使用一个数组来存储指向链表头部的指针,每个链表存储具有相同哈希值的元素。如果发生冲突,新的元素将被添加到该链表的末尾。这种方法可以避免聚集,但不保持元素的顺序。

    链地址法(c语言实现):

    1. #include
    2. #include
    3. #define SIZE 20
    4. typedef struct Node {
    5. int value;
    6. int key;
    7. struct Node* next;
    8. }Node;
    9. typedef struct{
    10. Node *table[SIZE];
    11. }HashTable;
    12. //初始化哈希表
    13. void initHashTable(HashTable *ht){
    14. for (int i = 0; i < SIZE; i++) {
    15. ht->table[i] = NULL;
    16. }
    17. }
    18. int getKey(int value){
    19. return value%SIZE;
    20. }
    21. //向哈希表中插入数据 hash公式就是 value%20
    22. void addvalue(int value,HashTable *ht){
    23. Node *node=(Node*)malloc(sizeof(Node));
    24. node->value=value;
    25. int key=getKey(value);
    26. node->key=key;
    27. node->next=NULL;
    28. Node *tmp=ht->table[key];
    29. if(tmp!=NULL){
    30. while(tmp->next){
    31. tmp=tmp->next;
    32. }
    33. tmp->next=node;
    34. }else{
    35. ht->table[key]=node;
    36. }
    37. }
    38. //查看哈希表中是否包含此值
    39. int containValue(int value,HashTable *ht){
    40. int key=getKey(value);
    41. if(key<0){
    42. printf("查询非法数据!");
    43. return -1;
    44. }
    45. Node* tmp=ht->table[key];
    46. if(tmp==NULL) return 0;
    47. while(tmp){
    48. if(tmp->value==value) return 1;
    49. tmp=tmp->next;
    50. }
    51. return 0;
    52. }
    53. // 释放哈希表内存
    54. void freeHashTable(HashTable *ht) {
    55. for (int i = 0; i < SIZE; i++) {
    56. Node *current = ht->table[i];
    57. while (current != NULL) {
    58. Node *temp = current;
    59. current = current->next;
    60. free(temp);
    61. }
    62. }
    63. }
    64. int main(){
    65. HashTable table;
    66. initHashTable(&table);
    67. addvalue(1,&table);
    68. addvalue(3,&table);
    69. addvalue(6,&table);
    70. addvalue(7,&table);
    71. addvalue(11,&table);
    72. addvalue(23,&table);
    73. addvalue(21,&table);
    74. addvalue(27,&table);
    75. addvalue(87,&table);
    76. printf("%d\n",containValue(-1,&table));
    77. freeHashTable(&table);
    78. system("pause");
    79. return 0;
    80. }
    链地址法重点操作图解:

    链地址法(java语言实现):

    1. package linearList;
    2. /*
    3. * 采用链地址法实现哈希表
    4. * */
    5. class HashNode{
    6. int value;
    7. HashNode next;
    8. public HashNode(int value, HashNode next) {
    9. this.value = value;
    10. this.next = next;
    11. }
    12. }
    13. public class HashTable {
    14. HashNode hashNodes[];
    15. int size;
    16. public HashTable(int size) {
    17. this.size=size;
    18. this.hashNodes = new HashNode[size];
    19. for (int i = 0; i < size; i++) {
    20. hashNodes[i]=null;
    21. }
    22. }
    23. int getKey(int value){
    24. return value%size;
    25. }
    26. //向哈希表中插入数据
    27. HashTable addvalue(int value){
    28. int key = getKey(value);
    29. HashNode newNode = new HashNode(value, null);
    30. if (hashNodes[key]!=null){
    31. HashNode curNode=hashNodes[key];
    32. while (curNode.next!=null){
    33. curNode=curNode.next;
    34. };
    35. curNode.next=newNode;
    36. }else{
    37. hashNodes[key]=newNode;
    38. }
    39. return this;
    40. }
    41. //是否包含某值
    42. boolean containValue(int value){
    43. int key = getKey(value);
    44. if (hashNodes[key]==null){
    45. return false;
    46. }else{
    47. HashNode curNode=hashNodes[key];
    48. while (curNode!=null&&curNode.value!=value){
    49. curNode=curNode.next;
    50. }
    51. return curNode!=null?true:false;
    52. }
    53. }
    54. }
    55. class HashTableTest{
    56. public static void main(String[] args) {
    57. HashTable hashTable = new HashTable(10);
    58. hashTable.addvalue(11).addvalue(21).addvalue(13).addvalue(23).addvalue(4).addvalue(10);
    59. System.out.println(hashTable.containValue(24));
    60. }
    61. }

    开放寻址法(c语言实现):

    1. #include
    2. #include
    3. #define SIZE 100
    4. typedef struct Node {
    5. int value;
    6. int key;
    7. struct Node* next;
    8. }Node;
    9. typedef struct {
    10. Node* node[SIZE];
    11. int magnification;
    12. }HashTable;
    13. void initHashTable(HashTable *ht){
    14. int i;
    15. for(i=0;i
    16. ht->node[i]=NULL;
    17. }
    18. ht->magnification=1;
    19. }
    20. //获取索引,-2:该元素已经无法插入,-1:非法值
    21. int getKey(int value,HashTable *ht){
    22. int key=value%SIZE;
    23. if(key>=0&&ht->node[key]!=NULL){
    24. int i;
    25. for(i=key+1;i
    26. if(ht->node[i]==NULL) return i;
    27. }
    28. return -2;
    29. }else if(ht->node[key]==NULL){
    30. return key;
    31. }
    32. return -1;
    33. }
    34. void pushToHt(int value,HashTable *ht){
    35. int key=getKey(value,ht);
    36. if(key==-1){
    37. printf("非法值的查找!\n");
    38. }else if(key==-2){
    39. printf("%d插入失败!\n",value);
    40. }else{
    41. Node *node=(Node*)malloc(sizeof(Node));
    42. node->key=key;
    43. node->value=value;
    44. node->next=NULL;
    45. ht->node[key]=node;
    46. }
    47. }
    48. int containValue(int value,HashTable *ht){
    49. int key=value%SIZE;
    50. if(key==-1){
    51. printf("查询非法数据!\n");
    52. return -1;
    53. }else{
    54. return ht->node[key]!=NULL&&ht->node[key]->value==value?1:0;
    55. }
    56. }
    57. int main(){
    58. HashTable ht;
    59. initHashTable(&ht);
    60. pushToHt(1,&ht);
    61. pushToHt(2,&ht);
    62. pushToHt(23,&ht);
    63. pushToHt(11,&ht);
    64. pushToHt(12,&ht);
    65. pushToHt(14,&ht);
    66. pushToHt(5,&ht);
    67. pushToHt(15,&ht);
    68. pushToHt(31,&ht);
    69. printf("%d\n",containValue(14,&ht));
    70. system("pause");
    71. return 0;
    72. }
    开放寻址重点操作图解:

    开放寻址法(java语言实现):

    1. package linearList;
    2. /*
    3. * 采用开放寻址法实现哈希表
    4. * */
    5. public class HashOpenTable{
    6. int values[];
    7. int size;
    8. public HashOpenTable(int size) {
    9. this.size=size;
    10. values=new int[size];
    11. for (int i = 0; i < size; i++) {
    12. values[i]=-1;
    13. }
    14. }
    15. //获取索引,-2:该元素已经无法插入,-1:非法值
    16. public int getKey(int value){
    17. int key=value%this.size;
    18. if (key>=0&&values[key]!=-1){
    19. for (int i = key+1; i < size; i++) {
    20. if (values[i]==-1) return i;
    21. }
    22. return -2;
    23. }else if (values[key]==-1){
    24. return key;
    25. }else {
    26. return -1;
    27. }
    28. }
    29. //向哈希表中插入数据
    30. HashOpenTable addvalue(int value){
    31. int key=getKey(value);
    32. if (key==-1){
    33. System.out.println("非法值的输入");
    34. }else if (key==-2){
    35. System.out.println("此数值不能插入哈希表!");
    36. }else {
    37. values[key]=value;
    38. }
    39. return this;
    40. }
    41. //查看哈希表中是否包含某值
    42. boolean containValue(int value){
    43. int key=value%this.size;
    44. if (key==-1)
    45. return false;
    46. else{
    47. for (int i = key; i < size; i++) {
    48. if (values[i]==value) return true;
    49. }
    50. return false;
    51. }
    52. }
    53. }
    54. class HashOpenTableTest{
    55. public static void main(String[] args) {
    56. HashOpenTable hashOpenTable = new HashOpenTable(10);
    57. hashOpenTable.addvalue(1).addvalue(2).addvalue(4).addvalue(12).addvalue(14);
    58. System.out.println(hashOpenTable.containValue(12));
    59. }
    60. }

  • 相关阅读:
    【Oracle APEX开发小技巧2】在不通过类型转换的前提下使用Oracle APEX自带的格式掩码实现数值的精确展现
    安全狗安装
    如何给R128在FreeRTOS下配置/data目录
    Python 教程之从头开始构建个人助理,如何在 Python 中构建概念验证个人助理:意图分类、语音到文本和文本到语音(教程含源码)
    入门力扣自学笔记190 C++ (题目编号:481)
    c# winform程序,DispatcherTimer被调用延迟,响应间隔长
    栈——火车进出栈问题(卡特兰数,组合计数+高精度乘法+筛质数+求n的阶乘里的质因数次数(模板))
    Flask 学习-78.Flask-SQLAlchemy 一对多关系
    【JQuery_Ajax_方法使用】Ajax的JQuery函数/方法
    URL组成及对应的编程变量
  • 原文地址:https://blog.csdn.net/m0_57254953/article/details/133843953