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

本文介绍了使用搜索(查找)二叉树和哈希表的数据结构在嵌入式开发中的应用,包括平衡二叉树的选择、哈希函数设计、数据插入、查找操作以及哈希表的销毁和遍历。作者通过实例演示了如何创建哈希表并处理哈希冲突问题。
摘要由CSDN通过智能技术生成

我要成为嵌入式高手之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、低储存

         空间复杂度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值