队列(FIFO)first in first out
允许在两端进行插入和删除操作的线性表(队列)
有两个指针(1 取数据端 2 存数据端)
取出端称为 front
存入端称为 rear
队列的实现
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int data[6];
int rear;
int front;
}queue_t;
//创建队列
queue_t *CreateEmptyQueue()
{
queue_t *p = malloc(sizeof(queue_t));
p->rear = p->front = 0;
return p;
}
//判断是否为空
int EmptyQueue(queue_t *p)
{
return p->rear == p->front;
}
//判断是否为满
int FullQueue(queue_t *p)
{
return (p->rear + 1) % 6 == p->front;
}
//入队
int InQueue(queue_t *p, int x)
{
if(FullQueue(p))
{
printf("queue full\n");
return -1;
}
p->data[p->rear] = x;
p->rear++;
p->rear = p->rear % 6;
return 0;
}
//出队
int OutQueue(queue_t *p)
{
if(EmptyQueue(p))
{
printf("queue empty\n");
return -1;
}
int x = p->data[p->front];
p->front++;
p->front = p->front % 6;
return x;
}
int main()
{
queue_t *p = CreateEmptyQueue();
InQueue(p, 10);
InQueue(p, 20);
InQueue(p, 30);
InQueue(p, 40);
InQueue(p, 50);
InQueue(p, 60); //满,存入失败
printf("%d\n", OutQueue(p)); //10
printf("%d\n", OutQueue(p)); //20
printf("%d\n", OutQueue(p)); //30
printf("%d\n", OutQueue(p)); //40
printf("%d\n", OutQueue(p)); //50
printf("%d\n", OutQueue(p)); //空,-1
}
查找方法 :
现在介绍四种查找方法:顺序查找,二分法查找,分块查找与哈希表查找
1 顺序查找
在main函数里创建数组a, 然后输入一个数, 再写一个函数,
实现查找功能,如果找到了,返回找到的位置,如果没找到,返回-1
然后main函数调用此函数,打印是否找到
#include <stdio.h>
int find_by_order(int *p, int n, int x)
{
int i;
for(i = 0; i < n; i++)
{
if(p[i] == x)
{
return i; //结束整个函数
}
}
return -1;
}
int main()
{
int a[10] = {10, 15, 18, 20, 25, 30, 31, 38, 40 , 45};
int n;
scanf("%d", &n); //(38 7) (10 0) (11 not find)
int x = find_by_order(a, 10, n);
if(x >= 0)
printf("find it at %d\n", x);
else
printf("not find\n");
}
顺序查找的时间复杂度:O(n)
2 二分法查找(必须要保证数据是有序排列的)
每次找中间的数 和 x 进行比较,如果x比中间的数大,那么再在右面找中间的
如果x比中间的数小,那么再在左面找中间的
实现二分法查找
//while循环,结束条件? low > high
#include <stdio.h>
int find_by_half(int *p, int n, int x)
{
int l = 0, h = n - 1, m;
while(l <= h)
{
m = (l + h) / 2;
if(x > p[m])
{
l = m + 1;
}
else if(x < p[m])
{
h = m - 1;
}
else if(x == p[m])
{
return m;
}
}
return -1;
}
int main()
{
int a[10] = {10, 15, 18, 20, 25, 30, 31, 38, 40 , 45};
int n;
scanf("%d", &n); //(38 7) (10 0) (11 not find)
int x = find_by_half(a, 10, n);
if(x >= 0)
printf("find it at %d\n", x);
else
printf("not find\n");
}
二分法的时间复杂度:O(log(n))
3 分块查找
数据有如下特点:块间有序,块内无序
#include <stdio.h>
typedef struct
{
int max;
int pos;
}index_t;
int find_by_block(int *p, index_t *q, int x) //q 索引表
{
int i;
int start = 0, end = 0;
for(i = 0; i < 4; i++)
{
if(x <= q[i].max)
{ //找到了在哪块
start = q[i].pos;
if(i == 3)
end = 18;
else
end = q[i + 1].pos - 1;
break;
}
}
for(i = start; i <= end; i++)
{
if(p[i] == x)
return i;
}
return -1;
}
int main()
{ //1 构建原始数据表
int a[19] = {18, 10, 9, 8, 16, 20, 38, 42, 19, 50, 84, 72, 56, 55, 76, 100, 90, 88, 108};
//2 构建索引表, 用结构体数组
index_t b[4] = {{18, 0}, {50, 5}, {84, 10}, {108, 15}};
int n;
scanf("%d", &n);
int x = find_by_block(a, b, n);
if(x >= 0)
printf("find it at %d\n", x);
else
printf("not find\n");
}
4 哈希hash查找
//哈希表 哈希函数
哈希表又叫散列表(hash)
有一张表,表里面存的数据的某个关键字和位置有一个对应关系(关键字通过一个计算公式,能求出位置)
那么我们就可以快速找到某条记录
哈希查找有3个概念
1 关键字 (key)
2 计算公司(哈希函数 又称为 散列函数)
3 存储数据的表 (哈希表 又称为 散列表)
#include <stdio.h>
int hash_fun(int age)
{
return age - 1;
}
void save_by_hash(int *p, int age, int n)
{
int pos = hash_fun(age);
p[pos] = n;
}
int find_by_hash(int *p, int age)
{
int pos = hash_fun(age);
return p[pos];
}
int main()
{
int a[100] = { 0 }; //哈希表
int i, age, n;
for(i = 0; i < 5; i++) //输入5个年龄的人数, 存入哈希表
{
scanf("%d%d", &age, &n); //25 20000(25岁 20000个人)
save_by_hash(a, age, n);
}//查找某个年龄的人数
scanf("%d", &age);
n = find_by_hash(a, age);
printf("count is %d\n", n);
}
哈希查找练习:
叠加法练习(保留3位)
//1 写一个存储数据的函数
//2 写一个查找数据的函数
//3 用main函数测试
int a[] = {704005265, 103004265, 999000001, 54353524, 435645657, 321312};
上面的数,用叠加法,存入到哈希表中, 查询某个数是不是存在
#include <stdio.h>
int hash_fun(int x)
{
return (x / 1000000 + x % 1000000 / 1000 + x % 1000) % 1000;
}
void save_by_add(int *p, int x)
{
int pos = hash_fun(x);
if(p[pos] == 0)
p[pos] = x;
}
int find_by_hash(int *p, int x) //返回值: -1 没找到 >=0 位置
{
int pos = hash_fun(x);
if(p[pos] != x)
return -1;
else
return pos;
}
int main()
{
int a[] = {704005265, 103004265, 999000001, 54353524, 435645657, 321312};
int i, n, b[1000] = { 0 }; //哈希表
for(i = 0; i < 6; i++)
{
save_by_add(b, a[i]); //将6个ISBN编号存入到哈希表中
}
scanf("%d", &n); //输入一个ISBN编号,查找是否在哈希表中
int x = find_by_hash(b, n);
if(x >= 0)
printf("find it at %d\n", x);
else
printf("not find\n");
}