Name, age, height
Xiaoming 13 150
Xiaohong 12 135
Example: Find information about all students whose height is 150cm
顺序查找 - 什么样的数据都可以
typedef struct{
char name[10];
int age;
int high;
}stu_info;
int seq_select(stu_info *s, int n, int h, stu_info *result)
{
int i;
int con = 0;
for(i=0; i<n; i++){
if(h == s[i].high){
result[con] = s[i];
con++;
}
}
return con;
}
int main()
{
int ret, i;
int h;
stu_info s[ ] ={
{"a", 12, 150}, {"b", 11, 125}, {"c", 13, 155}, {"d", 12, 150},
{"e", 13, 150}};
stu_info r[3] = {0};
printf("input high:");
scanf("%d", &h);
ret = seq_select(s, 5, h, r);
for(i=0; i<ret; i++)
printf("%s-%d-%d\n", r[i].name, r[i].age, r[i].high);
return 0;
}
折半查找 - 二分查找 - 有序的数据
int bin_select(int *d, int n, int x){
int mid;
int beg = 0;
int end = n - 1;
while(beg <= end){
mid = (beg+end)/2;
if(d[mid] == x)
return mid;
else if(d[mid] > x)
end = mid - 1;
else
beg = mid + 1;
}
return -1;
}
int main()
{
int data[ ] = {1, 5, 19, 20, 48, 100, 299, 400};
int n = sizeof(data)/sizeof(int);
printf("1: %d\n", bin_select(data, n, 1));
printf("48: %d\n", bin_select(data, n, 48));
printf("400: %d\n", bin_select(data, n, 400));
printf("-100: %d\n", bin_select(data, n, -100));
printf("1000: %d\n", bin_select(data, n, 1000));
return 0;
}
索引查找 - 索引存储
备注名 手机号
小明 13807582345
typedef struct{
char name[10];
char phone[11];
}fre_info;
typedef struct{
char c;
int beg;
}suoyin;
int main()
{
int i, beg=0, end=0;
char name[10] = {0};
fre_info f[ ] = {
{"a", "1234"}, {"abc", "1256"}, {"acc", "1389"},
{"b", "2863"}, {"baby", "8563"}, {"c", "1235"},
{"cc", "1023"}, {"d", "1204"}, {"e", "1209"}, {"et", "1704"}};
int n = sizeof(f)/sizeof(f[0]);
suoyin s[5] = {
{'a', 0}, {'b', 3}, {'c', 5}, {'d', 7}, {'e', 8}};
printf("input select name:");
scanf("%s", name);
//在索引表中查找,确定所在的区间
for(i=0; i<5; i++){
if(name[0] == s[i].c){
beg = s[i].beg;
if(i == 4){
end = n-1;
} else{
end = s[i+1].beg - 1;
}
}
}
//在区间内顺序查找
for(i=beg; i<=end; i++){
if(strcmp(f[i].name, name) == 0){
printf("%s - %s\n", f[i].name, f[i].phone);
return 0;
}
}
printf("not found\n");
}
hash表查找 - 散列存储
存储数据的关键字跟位置之间的关系 - hash函数
1. 直接地址法
学号 学生(信息)
170201
170202
170203
.....
关键字:学号 key
位置:pos
pos = key - 170201
typedef struct{
int no;
int math;
int english;
}stu_info;
//hash查找
int hash_select(stu_info *d, int n, int no){
int pos = hash_fun(no);
if(pos<0 || pos>n-1){
printf("pos error,not found\n");
return -1;
}
if(no == d[pos]){
printf("%d - %d - %d\n", d[pos].no, d[pos].math, d[pos].english);
return 1;
}
printf("not found\n");
return -1;
}
//hash函数
int hash_fun(int key){
int pos;
pos = key - 170201;
return pos;
}
int main(void){
//建立hash表
int i, pos, no;
stu_info s;
stu_info data[60] = {0};
for(i=1; i<=5; i++){
printf("no - math - english\n");
scanf("%d%d%d", &s.no, &s.math, &s.english);
pos = hash_fun(s.no);
data[pos] = s;
}
//查找
printf("input select no:");
scanf("%d", &no);
hash_fun(data, 60, no);
return 0;
}
保留余数法
11 15 17 24 3 7 49 52 67
0 4 6 2 3 7 5 8 1
pos = key % m;
表的长度为n,m为不大于n的最大的质数
n - 12 m - 11
int hash_fun(int key)
{
return key%11;
}
int hash_select(int *d, int x)
{
int pos = hash_fun(x);
if(x == d[pos]){
printf("find\n");
return 1;
}
printf("not found\n");
return -1;
}
int main()
{
int pos, i;
int x;
int data[12];
for(i=1; i<=5; i++){
scanf("%d", &x);
pos = hash_fun(x);
data[pos] = x;
}
printf("input a num:");
scanf("%d", &x);
hash_select(data, x);
}
hash表查找 – 解决冲突的方法
1. 备用表
2. 链地址法
//hash函数
int hash_fun(int key)
{
return key%11;
}
//hash查找
int hash_select(link_node_t *d[], int x)
{
int pos;
link_node_t *p = NULL;
//根据要查找的数据计算出位置
pos = hash_fun(x);
//找到对应位置的头结点,遍历这条链表 - d[pos]
p = d[pos]->next;
while(p != NULL){
if(x == p->data){
printf("find\n");
return 1;
}
p = p->next;
}
printf("not found\n");
return -1;
}
int main(int argc, char *argv[])
{
int i, pos, x;
//定义指针数组,初始化,数组中每一个元素都是一个链表的头结点
link_node_t *data[12];
for(i=0; i<12; i++){
data[i] = create_link_list();
}
//存储数据 - 键盘接收
for(i=1; i<10; i++){
printf("input a num:");
scanf("%d", &x);
pos = hash_fun(x);
//链表的头结点 - data[pos]
insert_frist(data[pos], x);
}
for(i=1; i<5; i++){
printf("input select num:");
scanf("%d", &x);
hash_select(data, x);
}
return 0;
}
3. 叠加法
快递单号 物流信息
1234562 ....
1234566
pos = key%1000 + (key/1000)%1000 + key/1000000