• 哈希表


    哈希

    哈希又名散列法,是一种特殊的查找方法

    哈希法是希望不通过任何的比较,一次存取就能得到元素

    一、设计哈希表

    1.确定表的空间范围,确定哈希值域

    2.构造一个合适的哈希函数,这个函数要确保表中的元素经过该函数的计算之后,函数的返回值的范围在哈希值域之内

    3.选择处理冲突的方法(用链式结构)

    二、哈希函数

    定义好的哈希函数是哈希表设计的关键

    1.自身函数

    2.数字分析法(数字叠加法,数字求余法等)

    三、哈希示例

    #include<iostream>
    using namespace std;
    
    
    struct mynode//链式结构(处理冲突)
    {
    	int data;
    	mynode *pnext;
    };
    
    struct hashtable
    {
    	
    	mynode* val[10];//定义一个指针数组,里面每一个元素都是一个指针,指向一个链表,可以理解为每一个链表的头指针
    };
    
    hashtable* createhashtable()//创建一个哈希表
    {
    	hashtable* phash = new hashtable;//new了40个字节大小的内存
    	memset(phash, 0, sizeof(hashtable));//将phash全部赋0
    	return phash;
    }
    
    bool inserthashtable(hashtable* phash, int data)//插入数据
    {
    	if (phash == nullptr)//哈希表不存在就直接退出不用插入数据
    		return false;
    
    	//申请一个节点来保存要插入的数据,就是内部数据内部管理
    	mynode* pnode = new mynode;
    	pnode->data = data;
    	pnode->pnext = nullptr;//内部数据内部管理
    
    	if (phash->val[data % 10] == nullptr)//如果链表不存在
    		phash->val[data % 10] = pnode;
    	else
    	{
    		//如果链表存在
    		//用ptemp这个指针去指向链表头指针,方便接下来的操作
    		mynode* ptemp = phash->val[data % 10];
    		while (ptemp->pnext)
    		{
    			ptemp = ptemp->pnext;
    		}
    		ptemp->pnext = pnode;
    	}
    	return true;
    
    }
    
    //查找数据
    mynode* finddatahash(hashtable* phash, int findata)
    {
    	if (phash == nullptr)//哈希表为空,直接退出
    		return nullptr;
    
    	//先找到你要查找的链表
    	mynode* pnode = phash->val[findata % 10];
    	if (pnode == nullptr)
    		return nullptr;
    	while (pnode)
    	{
    		if (pnode->data == findata)
    			return pnode;
    		pnode = pnode->pnext;
    	}
    	return nullptr;
    }
    
    //删除数据
    bool deletedatahash(hashtable* phash, int deldata)
    {
    	//用一个节点来接收,查找到的节点
    	mynode* pnode = finddatahash(phash, deldata);
    	if (pnode == nullptr)
    		return false;
    
    	//接收链表头
    	mynode* ptemphead = phash->val[deldata % 10];
    	if (ptemphead == pnode)
    	{
    		//如果要删除的节点就是链表的头节点,那么直接让原来的头指针指向头节点之后的那一个节点
    		phash->val[deldata % 10] = pnode->pnext;
    	}
    	else
    	{
    		while (ptemphead->pnext != pnode)
    		{
    			ptemphead = ptemphead->pnext;
    		}
    		//相当于是pnode=pnode->pnext;
    		ptemphead->pnext = pnode -> pnext;
    	}
    	delete pnode;
    	return true;
    }
    void clearhashtabl(hashtable*&phash)
    {
    	if (phash == nullptr)
    		return;
    
    	mynode* phead = nullptr;
    	mynode* pcurrent = nullptr;
    	for (int i = 0; i < 10; i++)
    	{
    		if ((phead = phash->val[i]) != nullptr)
    		{
    			while (phead)
    			{
    				pcurrent = phead;
    				phead = phead->pnext;
    				delete pcurrent;
    			}
    		}
    	}
    	delete[]phash;
    	phash = nullptr;//如果这里不用引用,那么就不能赋空值,因为赋空值只是给phash这个形参赋的,没有影响到实参phash
    }
    
    int main()
    {
    	hashtable* phash = nullptr;
    	phash = createhashtable();//在堆区创建哈希表的内存空间
    	inserthashtable(phash, 1);
    	inserthashtable(phash, 21);
    	inserthashtable(phash, 31);
    	inserthashtable(phash, 41);
    	deletedatahash(phash, 1);
    	clearhashtabl(phash);
    	return 0;
    }
    
  • 相关阅读:
    学习网站
    Windows下python安装运行
    Python学习
    ES学习
    Eclipse安装lombok及常用注解
    Spark学习资料
    Spring Cloud学习资料
    使用Excel过滤重复数据
    Excel根据字符串截取单元格部分内容
    Spring中@Transactional(rollbackFor = Exception.class)的作用
  • 原文地址:https://www.cnblogs.com/Kissfly123/p/14637925.html
Copyright © 2020-2023  润新知