平均查找长度(散列 顺序 二分)

以学生班级 姓名作为信息,进行平均查找长度的演示

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#define STUDENTS_SUM 30	//学生总数
#define HASH_TABLE_SIZE 40	//哈希表长度
#define MAX_PRIME 37	//小于等于哈希表长度大于元素个数的最大素数

typedef struct student_message	//学生学习结构体
{
	char _class[10];	//班级
	char name[30];	//姓名(关键词)
}STU_Message;

STU_Message* create_Hash(STU_Message messages[STUDENTS_SUM]);	//哈希表创建
int assign(STU_Message* message, STU_Message* temp);	//结构体赋值
double hash_Search(STU_Message messages[STUDENTS_SUM]);	//散列查找
double order_Search(STU_Message messages[STUDENTS_SUM]);	//顺序查找
double binary_Search(STU_Message messages[STUDENTS_SUM]);	//二分查找
int messages_Compare(const void* a, const void* b);	//比较结构体大小
int hash(STU_Message temp);	//计算哈希值
int division_Method(STU_Message temp);	//除留余数法
int rehash(STU_Message temp, int j);	//线性探测再散列法
int init_Message(char FILE_NAME[30]);	//初始化文件信息
STU_Message* file_Read(char FILE_NAME[30]);	//读取文件信息

int main(int argc,char** argv)
{
	char FILE_NAME[30] = "Message.txt";
	STU_Message* students_messages = NULL;

	init_Message(FILE_NAME);
	students_messages = file_Read(FILE_NAME);

	printf("散列查找算法的平均查找长度为 %lf\n", hash_Search(students_messages));
	printf("顺序查找算法的平均查找长度为 %lf\n", order_Search(students_messages));
	printf("二分查找算法的平均查找长度为 %lf\n", binary_Search(students_messages));

	return 0;
}

STU_Message* create_Hash(STU_Message messages[STUDENTS_SUM])	//哈希表创建
{
	int i, j;
	int hash_code;
	STU_Message* hash_table = (STU_Message*)malloc(sizeof(STU_Message) * HASH_TABLE_SIZE);
	STU_Message temp = {"0", "0"};

	for (i = 0; i < STUDENTS_SUM; i++)
	{
		assign(&hash_table[i], &temp);
	}

	for (i = 0; i < STUDENTS_SUM; i++)
	{
		hash_code = division_Method(messages[i]);
		if (hash_table[hash_code].name[0] == '0'){
			assign(&hash_table[hash_code], &messages[i]);
		}
		else{
			for (j = 1; hash_table[hash_code].name[0] != '0'; j++)
			{
				hash_code = rehash(messages[i], j);
			}
			assign(&hash_table[hash_code], &messages[i]);
		}
	}

	return hash_table;
}

int assign(STU_Message* message, STU_Message* temp)	//结构体赋值
{
	strcpy(message->_class, temp->_class);
	strcpy(message->name, temp->name);
	return 1;
}

double hash_Search(STU_Message messages[STUDENTS_SUM])	//散列查找
{
	int i, j;
	int hash_code;
	double total_serach_length = 0, average_search_length, i_length;
	STU_Message* hash_table = create_Hash(messages);

	for (i = 0; i < STUDENTS_SUM; i++)
	{
		i_length = 1;	//查找长度初始化为 1
		hash_code = division_Method(hash_table[i]);
		if (hash_table[hash_code].name == NULL){
			puts("哈希表非法空值!!!");
			exit(1);
		}
		else if (strcmp(hash_table[hash_code].name, messages[i].name) == 0){
		}
		else{
			for (j = 1; strcmp(hash_table[hash_code].name, messages[i].name) != 0; j++)
			{
				i_length++;	//查找长度加一
				hash_code = rehash(messages[i], j);
			}
		}

		total_serach_length += i_length;
	}
	average_search_length = total_serach_length / STUDENTS_SUM;

	return average_search_length;	//返回平均查找长度
}

double order_Search(STU_Message messages[STUDENTS_SUM])	//顺序查找
{
	int i, j;
	double total_serach_length = 0, average_search_length, i_length;

	for (i = 0; i < STUDENTS_SUM; i++)
	{
		for (j = 0, i_length = 0; j < STUDENTS_SUM; j++)
		{
			i_length++;	//查找长度加一
			if (strcmp(messages[j].name, messages[i].name) == 0){
				break;
			}
		}

		total_serach_length += i_length;
	}
	average_search_length = total_serach_length / STUDENTS_SUM;

	return average_search_length;	//返回平均查找长度
}

double binary_Search(STU_Message messages[STUDENTS_SUM])	//二分查找
{
	int i, high, low, mid;
	double total_serach_length = 0, average_search_length, i_length;

	qsort(messages, STUDENTS_SUM, sizeof(STU_Message), messages_Compare);	//快速排序
	for (i = 0; i < STUDENTS_SUM; i++)
	{
		for (low = 0, high = STUDENTS_SUM - 1, i_length = 0; low <= high; )
		{
			i_length++;	//查找长度加一
			mid = (low + high) / 2;
			if (strcmp(messages[mid].name, messages[i].name) == 0){
				break;
			}
			else if (strcmp(messages[mid].name, messages[i].name) < 0){
				high = mid - 1;
			}
			else{
				low = mid + 1;
			}
		}

		total_serach_length += i_length;
	}
	average_search_length = total_serach_length / STUDENTS_SUM;

	return average_search_length;	//返回平均查找长度
}

int messages_Compare(const void* a, const void* b)	//比较结构体大小
{
	return strcmp(((STU_Message*)b)->name, ((STU_Message*)a)->name);	//升序排序
}

int hash(STU_Message temp)	//计算哈希值
{
	int i;
	int weight_sum, weight_class, weight_name, name_length = strlen(temp.name);

	for (i = 0, weight_name = 0; i < name_length; i++)
	{
		weight_name += temp.name[i] * pow(13, 2);
	}
	weight_class = 0;
	weight_sum = weight_class + weight_name;
	return weight_sum;
}

int division_Method(STU_Message temp)	//除留余数法
{
	return (hash(temp) % MAX_PRIME);
}

int rehash(STU_Message temp, int j)	//线性探测再散列法
{
	return ((hash(temp) + j) % HASH_TABLE_SIZE);
}

int init_Message(char FILE_NAME[30])	//初始化文件信息
{
	int i;
	FILE* file = NULL;
	char string[STUDENTS_SUM][30]={
		"class2 zhangsan",
		"class2 lisi",
		"class3 wangmazi",
		"class3 ergoudan",
		"class4 tieniu",
		"class4 dabendan",
		"class5 xunan",
		"class5 zhoulei",
		"class6 tanglei",
		"class6 xiaomin",
		"class7 xiaohong",
		"class7 xiaoli",
		"class8 damin",
		"class8 jinzhengyu",
		"class9 xiasaobi",
		"class9 xuyang",
		"class10 lihao",
		"class10 huangzhifeng",
		"class11 liangsifen",
		"class11 yanzhiwo",
		"class12 liyanlin",
		"class12 liuxiaohan",
		"class13 tanghuan",
		"class13 gongxiaoyu",
		"class14 haoren",
		"class14 huairen",
		"class15 shuchang",
		"class15 lixinru",
		"class16 zhouhang",
		"class16 wangcunwen"};

	if ((file = fopen(FILE_NAME, "w")) == NULL){
		printf("%s 文件打开失败!!!\n",FILE_NAME);
		exit(1);
	}

	for (i = 0; i < STUDENTS_SUM; i++)
	{
		if (
			fprintf(file, "%s\n", string[i]) == EOF){
			printf("第 %d 个学生的信息写入失败!!!\n", i + 1);
			exit(1);
		}
	}
	if (fclose(file) == EOF){
		puts("文件关闭失败!!!");
		exit(1);
	}
	return 1;
}

STU_Message* file_Read(char FILE_NAME[30])	//读取文件信息
{
	FILE* file = NULL;
	int i;
	STU_Message* students_messages = (STU_Message*)malloc(sizeof(STU_Message) * STUDENTS_SUM);

	if ((file = fopen(FILE_NAME, "r")) == NULL){
		printf("%s 文件不存在!!!\n",FILE_NAME);
		exit(1);
	}

	for (i = 0; i < STUDENTS_SUM; i++)
	{
		if (fscanf(file, "%s %s", students_messages[i]._class, students_messages[i].name) == EOF){
			printf("第 %d 个学生的信息读取失败!!!\n", i + 1);
			exit(1);
		}
	}
	if (fclose(file) == EOF){
		puts("文件关闭失败!!!");
		exit(1);
	}
	puts("全部学生信息读取成功!!!");
	
	return students_messages;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值