哈希存储、哈希表、哈希表的基本操作、算法的一些概念

news2024/12/24 8:29:58

我要成为嵌入式高手之3月25日数据结构第七天!!
—————————————————————————————

搜索(查找)二叉树

思想:左大右小

主要为了进行二分查找,由于根节点选择不合适,容易造成树不平衡,故产生了平衡二叉树

哈希存储(散列存储)

为了快速定位数据

哈希表

哈希冲突 / 哈希矛盾

关键字不一样,但是映射之后结果一样

如何避免 哈希矛盾?

1、重新设计哈希函数,尽可能均匀散列分布在哈希表

2、开放定址法:向下寻找未存储的位置进行存放数据

3、链地址法: 将数据链表的首地址存入哈希表,只需将数据结点往链表后链接即可

1、创建哈希表

HASH_NODE *hash_table[HASH_SIZE] = {NULL};

2、设计哈希函数

int HashFun(char ch)
{
    if (ch >= 'a' && ch <= 'z')
    {
        return ch - 'a';
    }
    else if (ch >= 'A' && ch <= 'Z')
    {
        return ch - 'A';
    }
    else
    {
        return HASH_SIZE-1;
    }
}

3、数据插入哈希表

int InsertHashTable(DATA_TYPE data)
{
    HASH_NODE *pnode = malloc(sizeof(HASH_NODE));
    if (NULL == pnode)
    {
        perror("fail to malloc pnode");
        return -1;
    }
    pnode->data = data;
    pnode->pnext = NULL;

    int addr = HashFun(data.name[0]);

    if (IsEmpty(addr))
    {
        hash_table[addr] = pnode;
    }
    else
    {
        pnode->pnext = hash_table[addr];
        hash_table[addr] = pnode;
    }
}

4、数据查找

int SearchInHashTable(char *tmpname)
{
    HASH_NODE *ptmp = NULL;

    int addr = HashFun(tmpname[0]);
    if (IsEmpty(addr))
    {
        printf("查无此人!\n");
        return -1;
    }
    else
    {
        ptmp = hash_table[addr];
        while (ptmp != NULL)
        {
            if (!strcmp(ptmp->data.name, tmpname))
            {
                printf("该人的信息如下:\n");
                printf("name: %s\n tel: %s\naddr: %s\n", ptmp->data.name, ptmp->data.tel, ptmp->data.addr);
                return 0;
            }
            else
            {
                ptmp = ptmp->pnext;
            }
        }
        printf("查无此人!\n");
        return -1;
    }
}

5、销毁哈希表

int DestroyHashTable()
{
    HASH_NODE *ptmp = NULL;
    HASH_NODE *pfree = NULL;

    int addr = 0;
    for (addr =0; addr < HASH_SIZE; ++addr)
    {
        if (IsEmpty(addr))
        {
            continue;
        }
        ptmp = hash_table[addr];
        while (ptmp != NULL)
        {
            pfree = ptmp;
            ptmp = ptmp->pnext;
            free(pfree);
        }
    }
}

6、遍历

void SearchAll()
{
    HASH_NODE *ptmp = NULL;
    int i = 0;
    
    for (i = 0; i < HASH_SIZE; ++i)
    {
        if (IsEmpty(i))
        {
            continue;
        }
        else
        {
            ptmp = hash_table[i];
            while (ptmp != NULL)
            {
                printf("name[%d]: %s\n", i, ptmp->data.name);
                ptmp = ptmp->pnext;
            }
        }
    }
}

总程序:

main.c

#include "hash.h"

int main()
{
    DATA_TYPE pers[4] = {
        {"zhangsan", "110", "xian"},
        {"lisi", "120", "beijing"},
        {"wangwu", "119", "guangzhou"},
        {"liuqi", "12315", "shenzhen"},
    };

    InsertHashTable(pers[0]);
    InsertHashTable(pers[1]);
    InsertHashTable(pers[2]);
    InsertHashTable(pers[3]);

    char  tmp[32] = {0};
    printf("请输入要查找的人的名字: ");
    fgets(tmp, sizeof(tmp), stdin);
    tmp[strlen(tmp)-1] = '\0';
    SearchInHashTable(tmp);
    printf("==============================\n");

    SearchAll();

    DestroyHashTable();

    return 0;
}

hash.c

#include "hash.h"

HASH_NODE *hash_table[HASH_SIZE] = {NULL};

int HashFun(char ch)
{
    if (ch >= 'a' && ch <= 'z')
    {
        return ch - 'a';
    }
    else if (ch >= 'A' && ch <= 'Z')
    {
        return ch - 'A';
    }
    else
    {
        return HASH_SIZE-1;
    }
}

int IsEmpty(int addr)
{
    if (hash_table[addr] == NULL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int InsertHashTable(DATA_TYPE data)
{
    HASH_NODE *pnode = malloc(sizeof(HASH_NODE));
    if (NULL == pnode)
    {
        perror("fail to malloc pnode");
        return -1;
    }
    pnode->data = data;
    pnode->pnext = NULL;

    int addr = HashFun(data.name[0]);

    if (IsEmpty(addr))
    {
        hash_table[addr] = pnode;
    }
    else
    {
        pnode->pnext = hash_table[addr];
        hash_table[addr] = pnode;
    }
}

void SearchAll()
{
    HASH_NODE *ptmp = NULL;
    int i = 0;
    
    for (i = 0; i < HASH_SIZE; ++i)
    {
        if (IsEmpty(i))
        {
            continue;
        }
        else
        {
            ptmp = hash_table[i];
            while (ptmp != NULL)
            {
                printf("name[%d]: %s\n", i, ptmp->data.name);
                ptmp = ptmp->pnext;
            }
        }
    }
}

int SearchInHashTable(char *tmpname)
{
    HASH_NODE *ptmp = NULL;

    int addr = HashFun(tmpname[0]);
    if (IsEmpty(addr))
    {
        printf("查无此人!\n");
        return -1;
    }
    else
    {
        ptmp = hash_table[addr];
        while (ptmp != NULL)
        {
            if (!strcmp(ptmp->data.name, tmpname))
            {
                printf("该人的信息如下:\n");
                printf("name: %s\n tel: %s\naddr: %s\n", ptmp->data.name, ptmp->data.tel, ptmp->data.addr);
                return 0;
            }
            else
            {
                ptmp = ptmp->pnext;
            }
        }
        printf("查无此人!\n");
        return -1;
    }
}

int DestroyHashTable()
{
    HASH_NODE *ptmp = NULL;
    HASH_NODE *pfree = NULL;

    int addr = 0;
    for (addr =0; addr < HASH_SIZE; ++addr)
    {
        if (IsEmpty(addr))
        {
            continue;
        }
        ptmp = hash_table[addr];
        while (ptmp != NULL)
        {
            pfree = ptmp;
            ptmp = ptmp->pnext;
            free(pfree);
        }
    }
}

hash.h

#ifndef _HASH_H
#define _HASH_H

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

#define HASH_SIZE 27

typedef struct per
{
    char name[32];
    char tel[32];
    char addr[64];
}DATA_TYPE;

typedef struct hasnode
{
    DATA_TYPE data;
    struct hasnode *pnext;
}HASH_NODE;

extern int HashFun(char ch);
extern int IsEmpty(int addr);
extern int InsertHashTable(DATA_TYPE data);
extern void SearchAll();
extern int SearchInHashTable(char *tmpname);
extern int DestroyHashTable();


#endif

算法

解决特定问题求解步骤

算法的设计

1、正确性

        语法正确

        合法的输入能得到合理的结果

        对非法的输入,给出满足要求的规格说明;对精心选择,甚至刁难的测试都能正常运行,结果正确

2、可读性

        便于交流,阅读,理解,高内聚,低耦合

3、健壮性

        输入非法数据,能进行相应的处理,而不是产生异常

4、高效率

        时间复杂度

        执行这个算法所花时间的度量

将数据量增长和时间增长用函数表示出来,这个函数就叫做时间复杂度

一般用大O表示法:O(n) —— 时间复杂度是关于数据n的一个函数,随着n的增加,时间复杂度增长较慢的算法时间复杂度低

时间复杂度的计算规则

        1,用常数1 取代运行时间中的所有加法常数

        2,在修改后的运行函数中,只保留最高阶项。

        3,如果最高阶存在且系数不是1,则去除这个项相乘的常数。

5、低储存

         空间复杂度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1544279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NOMA免调度接入技术

标题 系统模型 参考视频&#xff1a;添加链接描述 利用接收机的复杂度提升为代价&#xff0c;提升频谱效率。为了保证上行方向上面&#xff0c;能够接入更多的用户&#xff0c;NOMA的根本思路&#xff0c;就是让多个用户占用相同的资源进行上行传输 系统模型 采用TDMA的方式…

K8s-网络原理-下篇

引言 本文是《深入剖析 K8s》的学习笔记&#xff0c;相关图片和案例可从https://github.com/WeiXiao-Hyy/k8s_example中获取&#xff0c;欢迎Star! K8s 的网络隔离: NetWorkPolicy K8s 如何考虑容器之间网络的“隔离” -> NetWorkPolicy 以下是一个 NetWorkPolicy 的定义…

msvcp110.dll丢失修复办法

在计算机使用过程中&#xff0c;我们经常会遇到一些扩展名为.dll的文件&#xff0c;这些文件是动态链接库文件&#xff0c;用于提供程序运行时所需的函数和资源。其中&#xff0c;msvcp110.dll文件是一个非常重要的动态链接库文件&#xff0c;它属于Microsoft Visual C 2012 Re…

【vue核心技术实战精讲】1.3 - 1.5 VUE 指令 (上)

文章目录 前言 本节内容1、v-text 和 v-html代码效果 2、v-if 和 v-show代码效果 3、v-bind3.1、用法&#xff1a;v-bind: 属性 &#xff0c;简写 :3.2、动态 attribute 名效果 3.3、内联字符串拼接效果 3.4、绑定 class效果 3.5、style 绑定3.6、绑定一个全是 attribute 的对…

学点儿Java_Day10_集合框架(List、Set、HashMap)

1 简介 ArrayList: 有序(放进去顺序和拿出来顺序一致)&#xff0c;可重复 HashSet: 无序(放进去顺序和拿出来顺序不一定一致)&#xff0c;不可重复 Testpublic void test1() {String[] array new String[3];//List: 有序 可重复//有序: 放入顺序 与 拿出顺序一致&#xff0c;…

精酿啤酒:酿造工艺的传承与改进

啤酒酿造工艺是一种历史悠久且不断发展的技艺&#xff0c;它随着时代的变化和技术的进步不断得到改进和创新。Fendi Club啤酒作为一家精酿啤酒品牌&#xff0c;在传承经典酿造工艺的同时&#xff0c;也不断探索和改进&#xff0c;以满足现代消费者的需求。 Fendi Club啤酒传承了…

蓝桥杯物联网遇见的重大BUG及其产生原因和解决方法

BUG列表 1、ADC的RP2显示一直为0&#xff1a;2、LORX_Tx发送数据乱码&#xff1a;3、strcmp比较char a[2] {1, 2}与“12”字符串是否相等板子会死机&#xff1a;4、LORA_Tx和LORA_Rx放一起会接收不到数据&#xff1a;5、RTC获取到静止时间&#xff1a;6、ADC获取RP1和RP2模拟量…

【k8s网络】梳理cni发展脉络

参考 《深入剖析 Kubernetes&#xff08;张磊&#xff09;》 补充 详解 Calico 三种模式&#xff08;与 Fannel 网络对比学习&#xff09;_calico vxlan-CSDN博客 容器网络 容器的网络栈 每个容器有自己的 net namespace net namespace 可以称之为网络栈所谓“网络栈”&…

睿考网:不是会计专业能考中级会计师吗?

不是会计专业也是可以考中级会计师的&#xff0c;中级会计师报名条件中并没有对专业做明确的限制&#xff0c;不同的学历对工作年限的要求不一样&#xff0c;如果考生满足报考条件就可以参加。 1.具备大学专科学历&#xff0c;从事会计工作满5年。 2.具备大学本科学历或学士学…

【Linux】进程的基本概念(进程控制块,ps命令,top命令查看进程)

目录 01.进程的基本概念 程序与进程 进程的属性 02.进程控制块&#xff08;PCB&#xff09; task_struct的内容分类 组织进程 03.查看进程 ps命令 top指令 在计算机科学领域&#xff0c;进程是一项关键概念&#xff0c;它是程序执行的一个实例&#xff0c;是操作系统的…

【Linux】线程预备知识{远程拷贝/重入函数与volatile关键字/认识SIGCHILD信号/普通信号/实时信号}

文章目录 0.远程拷贝1.重入函数与volatile关键字2.认识SIGCHILD信号3.普通信号/实时信号 0.远程拷贝 打包资源&#xff1a;tar czf code.tgz *远程传输&#xff1a;scp code.tgz usr服务器ip:/home/usr/路径解压&#xff1a;tar xzf code.tgz 1.重入函数与volatile关键字 先看…

【智能算法】秃鹰搜索算法(BES)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年&#xff0c; Alsattar等人受到秃鹰猎食自然行为启发&#xff0c;提出了秃鹰搜索算法&#xff08;Bald Eagle Search&#xff0c;BES&#xff09;。 2.算法原理 2.1算法思想 BES主要分为三…

龙智亮相2024国际集成电路展览会暨研讨会(IIC Shanghai),分享芯片研发及管理解决方案与技术实践

2024年3月28-29日&#xff08;周四-周五&#xff09;&#xff0c;上海张江科学会堂&#xff0c;2024国际集成电路展览会暨研讨会&#xff08;IIC Shanghai 2024&#xff09;即将盛大开幕。龙智携芯片研发及管理解决方案、最佳实践与案例&#xff0c;以及惊喜大奖在#1A14展位等着…

第十九章 linux部署scrapyd

文章目录 1. linux部署python环境1. 部署python源文件环境2. 下载python3. 解压安装包4. 安装5. 配置环境变量6. 检查是否安装成功7. 准备python使用的包8. 安装scrapyd9. 配置scrapyd10. 开放6800端口 2. 部署gerapy1. 本机下载包2. 初始化3. 进入gerapy同步数据库4. 创建用户…

堂哥让我给他做个真人动漫头像

背景 堂哥最喜欢的动漫是死神。他给了我一张死神主角一户的头像&#xff0c;以及自己的头像&#xff0c;希望我产出一张真人动漫头像。 一户的头像&#xff1a; 堂哥自拍照&#xff1a; 最近&#xff0c;有大佬部署了个stable diffusion&#xff0c;正好拿来一试身手。 stab…

优质视频素材库排行榜前十名有哪些?

在视频创作的世界中&#xff0c;每一帧画面、每一个音符都承载着无限的可能。为了帮助你更好地探索这些可能性&#xff0c;我继续为你精选了一系列素材网站。这些网站不仅能够提供高质量的视频、音效和图像素材&#xff0c;还能激发你的创意灵感&#xff0c;助你一臂之力。 1&…

利器 | 测试必会之 Linux 三剑客 ( grep / awk / sed )

Linux 给人的印象是黑乎乎的神秘窗口&#xff0c;文本操作和数据处理似乎没有 Windows 窗口界面直观方便。其实Linux 有自己的独特的法宝&#xff0c;称之为三剑客&#xff1a;grep&#xff0c;awk 和 sed。你可以用这三件法宝很方便的处理数据 &#xff1a;查找&#xff0c;分…

时间戳的转换-unix时间戳转换为utc时间(python实现)

import datetimetimestamp = 1711358882# 将时间戳转换为UTC时间 utc_time = datetime.datetime.utcfromtimestamp(timestamp)# 格式化并输出时间 formatted_time = utc_time.strftime(%Y-%m-%d %H:%M:%S) print(formatted_time)同样:UTC如何转换为unix时间戳 from datetime …

【考研数学】如何搭配好《660》+《880》组合?

如果1800题都做不明白&#xff0c;那就不要去做880题660题 做完1800题之后&#xff0c;还迷迷糊糊&#xff0c;解题水平极低&#xff0c;都是犯了一个错误&#xff1a; 那就是为了做题而做题&#xff01; 如果这个习惯不改掉&#xff0c;那不管是做660题还是880题都起不到任…