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