2022 C语言数据结构总结浅浅入门(5)队列与查找

队列(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");
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值