哈希表的实现

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

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

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

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

#include <stdio.h>
#include  <stdlib.h>

#define SIZE 20
typedef struct Node {
	int value;
	int key;
	struct Node* next;
}Node;

typedef struct{
	Node *table[SIZE];
}HashTable; 

//初始化哈希表
void initHashTable(HashTable *ht){
	for (int i = 0; i < SIZE; i++) {
        ht->table[i] = NULL;
    }
} 

int getKey(int value){
	return value%SIZE;
}

//向哈希表中插入数据  hash公式就是 value%20 
void addvalue(int value,HashTable *ht){
	Node *node=(Node*)malloc(sizeof(Node));
	node->value=value;
	int key=getKey(value);
	node->key=key;
	node->next=NULL;
	Node *tmp=ht->table[key];
	if(tmp!=NULL){
		while(tmp->next){
			tmp=tmp->next;	
		}
		tmp->next=node;
	}else{
		ht->table[key]=node; 
	} 
}

//查看哈希表中是否包含此值 
int containValue(int value,HashTable *ht){
	int key=getKey(value);
	if(key<0){
		printf("查询非法数据!");
		return -1;
	}
	Node* tmp=ht->table[key];
	if(tmp==NULL) return 0;
	while(tmp){
		if(tmp->value==value) return 1;
		tmp=tmp->next;
	}
	return 0;
}

// 释放哈希表内存
void freeHashTable(HashTable *ht) {
    for (int i = 0; i < SIZE; i++) {
        Node *current = ht->table[i];
        while (current != NULL) {
            Node *temp = current;
            current = current->next;
            free(temp);
        }
    }
}


int main(){
	HashTable table;
	initHashTable(&table);
	addvalue(1,&table);
	addvalue(3,&table);
	addvalue(6,&table);
	addvalue(7,&table);
	addvalue(11,&table);
	addvalue(23,&table);
	addvalue(21,&table);
	addvalue(27,&table);
	addvalue(87,&table);
	
	printf("%d\n",containValue(-1,&table));
	freeHashTable(&table);
	system("pause");
	return 0;
}
链地址法重点操作图解:

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

package linearList;

/*
* 采用链地址法实现哈希表
* */
class HashNode{
    int value;
    HashNode next;

    public HashNode(int value, HashNode next) {
        this.value = value;
        this.next = next;
    }
}
public class HashTable {
        HashNode hashNodes[];
        int size;

        public HashTable(int size) {
            this.size=size;
            this.hashNodes = new HashNode[size];
            for (int i = 0; i < size; i++) {
                hashNodes[i]=null;
            }
        }
        int getKey(int value){
            return value%size;
        }
       //向哈希表中插入数据
       HashTable addvalue(int value){
           int key = getKey(value);
           HashNode newNode = new HashNode(value, null);
           if (hashNodes[key]!=null){
               HashNode curNode=hashNodes[key];
               while (curNode.next!=null){
                   curNode=curNode.next;
               };
               curNode.next=newNode;
           }else{
               hashNodes[key]=newNode;
           }
           return this;
       }
       //是否包含某值
       boolean containValue(int value){
           int key = getKey(value);
           if (hashNodes[key]==null){
               return false;
           }else{
               HashNode curNode=hashNodes[key];
               while (curNode!=null&&curNode.value!=value){
                   curNode=curNode.next;
               }
               return curNode!=null?true:false;
           }
       }
}
class HashTableTest{
    public static void main(String[] args) {
        HashTable hashTable = new HashTable(10);
        hashTable.addvalue(11).addvalue(21).addvalue(13).addvalue(23).addvalue(4).addvalue(10);
        System.out.println(hashTable.containValue(24));
    }
}

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

#include <stdio.h>
#include  <stdlib.h>

#define SIZE 100

typedef struct Node {
	int value;
	int key;
	struct Node* next;
}Node;

typedef struct {
	Node* node[SIZE];
	int magnification;
}HashTable;

void initHashTable(HashTable *ht){
	int i;
	for(i=0;i<SIZE;i++){
		ht->node[i]=NULL;
	}
	ht->magnification=1;
}

//获取索引,-2:该元素已经无法插入,-1:非法值 
int getKey(int value,HashTable *ht){
	int key=value%SIZE;
	if(key>=0&&ht->node[key]!=NULL){
		int i;
		for(i=key+1;i<SIZE;i++){
			if(ht->node[i]==NULL) return i;
		}
		return -2;
	}else if(ht->node[key]==NULL){
		return key;
	}
	return -1;
}

void pushToHt(int value,HashTable *ht){
	int key=getKey(value,ht);
	if(key==-1){
		printf("非法值的查找!\n");
	}else if(key==-2){
		printf("%d插入失败!\n",value);
	}else{
		Node *node=(Node*)malloc(sizeof(Node));
		node->key=key;
		node->value=value;
		node->next=NULL;
		ht->node[key]=node;
	} 
}

int containValue(int value,HashTable *ht){
	int key=value%SIZE;
	if(key==-1){
		printf("查询非法数据!\n");
		return -1;
	}else{
		return ht->node[key]!=NULL&&ht->node[key]->value==value?1:0;
	}
}

int main(){
	HashTable ht;
	initHashTable(&ht);
	pushToHt(1,&ht);
	pushToHt(2,&ht);
	pushToHt(23,&ht);
	pushToHt(11,&ht);
	pushToHt(12,&ht);
	pushToHt(14,&ht);
	pushToHt(5,&ht);
	pushToHt(15,&ht);
	pushToHt(31,&ht);
	printf("%d\n",containValue(14,&ht));
	system("pause");
	return 0;
}
开放寻址重点操作图解:

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

package linearList;

/*
* 采用开放寻址法实现哈希表
* */
public class HashOpenTable{
    int values[];
    int size;

    public HashOpenTable(int size) {
        this.size=size;
        values=new int[size];
        for (int i = 0; i < size; i++) {
            values[i]=-1;
        }
    }
    //获取索引,-2:该元素已经无法插入,-1:非法值
    public int getKey(int value){
        int key=value%this.size;
        if (key>=0&&values[key]!=-1){
            for (int i = key+1; i < size; i++) {
                if (values[i]==-1) return i;
            }
            return -2;
        }else if (values[key]==-1){
            return key;
        }else {
           return -1;
        }
    }
    //向哈希表中插入数据
    HashOpenTable addvalue(int value){
        int key=getKey(value);
        if (key==-1){
            System.out.println("非法值的输入");
        }else if (key==-2){
            System.out.println("此数值不能插入哈希表!");
        }else {
            values[key]=value;
        }
        return this;
    }
    //查看哈希表中是否包含某值
    boolean containValue(int value){
        int key=value%this.size;
        if (key==-1)
            return false;
        else{
            for (int i = key; i < size; i++) {
                if (values[i]==value) return true;
            }
            return false;
        }
    }
}
class HashOpenTableTest{
    public static void main(String[] args) {
        HashOpenTable hashOpenTable = new HashOpenTable(10);
        hashOpenTable.addvalue(1).addvalue(2).addvalue(4).addvalue(12).addvalue(14);
        System.out.println(hashOpenTable.containValue(12));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值