数据结构--第八天

news2024/11/16 4:55:12

--哈希表

        -哈希表的概念

           哈希表:散列法存储的线性表被称为哈希表,使用的函数被称为散列函数或者哈希函数,f(k)被称为散列地址或者哈希地址。。通常情况下,散列表的储存空间是一个一维数组,而哈希地址为数组的下标

        -哈希表的基本思想

           以节点的关键字k为自变量,通过一个确定的函数关系f,计算出对应的函数值,把这个函数值解释为节点的存储地址,将节点存储到f(k)所指示的的存储位置上,在查找时再根据要查找的关键字,用同样的函数计算地址,然后到对应的单元读取。

        -哈希表的优点

           顺序表的特点是:寻址容易,插入和删除困难

           链表的特点是:寻址困难,插入和删除简单

           哈希表则结合了俩者的特点,既寻址容易又插入和删除容易

        -哈希冲突的解决方法

           开放地址法

             即当一个关键字和另一个关键字发生冲突时,使用某种探测技术在Hash表中形成  一个探测序列,然后沿着这个探测序列依次查找下去,当碰到一个空的单元时,则插入,比如有一组关键字{12,13,25,23,38,34,6,84,91},Hash表长为14,Hash函数为address(key)=key%11,当插入12,13,25时可以直接插入,而当插入23时,地址1被占用了,因此沿着地址1依次往下探测(探测步长可以根据情况而定),直到探测到地址4,发现为空,则将23插入其中。

           链地址法

             采用数组和链表相结合的办法,将Hash地址相同的记录存储在一张线性表中,而每张表的表头的序号即为计算得到的Hash地址。如上述例子中,采用链地址法形成的Hash表存储表示为:

            

示例代码:学生管理系统

        main.c
#include "linkedlist.h"

void menu();

int main(){
	while(!login_status){
		login();
	}
	int select;
	hash_t* hashtable=NULL;
	// 创建hashtable
	create_hashtable(&hashtable);
	if(NULL == hashtable){
		printf("hash table is NULL\n");
		exit(EXIT_FAILURE);
	}
	do{
		menu();	
		printf("请选择:");
		scanf("%d",&select);

		switch(select){
			case 1:
				insert_stu(hashtable);
				break;
			case 2:
				show_stus(hashtable);
				break;
			case 3:
				search_stu_by_id(hashtable);
				break;
			case 4:
				modify_stu_by_id(hashtable);
				break;
			case 5:
				del_stu_by_id(hashtable);
				break;
			case 0:
				printf("欢迎下次光临!\n");
				clear_hashtable(&hashtable);
				exit(EXIT_SUCCESS);
			case 6:
//				show_stus_linkedlist(hashtable);
				break;
		}
	}while(1);
}


void menu(){
	printf("-----------------------------------------\n");
	printf("|\t\t学生管理系统            |\n");
	printf("-----------------------------------------\n");
	printf("|\t\t1、增加学生    \t\t|\n");
	printf("|\t\t2、显示学生信息    \t|\n");
	printf("|\t\t3、查找学生    \t\t|\n");
	printf("|\t\t4、修改学生信息    \t|\n");
	printf("|\t\t5、删除学生    \t\t|\n");
	printf("|\t\t0、退出    \t\t|\n");
	printf("----------------------------------------\n");
}
        management.c
#include "linkedlist.h"

bool login_status=false;
void login(){
	printf("=============登录=============\n");
	printf("用户:");
	char uname[256]={0};
	fgets(uname,sizeof(uname),stdin);
	uname[strlen(uname)-1]='\0';
	printf("密码:");
	char password[256]={0};
	fgets(password,sizeof(password)-1,stdin);
	password[strlen(password)-1]='\0';
	if(strcmp(uname,"wq")==0&&strcmp(password,"wq")==0){
		printf("登录成功^_^\n");
		login_status=true;
	}else{
		printf("用户或密码错误\n");
	}
}

void create_hashtable(hash_t** hashtable){
	hash_t* p_hash=(hash_t*)malloc(sizeof(hash_t));
	if(NULL==p_hash){
		printf("malloc failure\n");
		return;
	}
	p_hash->n=0;
	for(int i=0;i<SIZE;i++){
		linkedlist_init(&(p_hash->item[i]));
	}
	*(hashtable)=p_hash;	
}

uint32_t get_hashindex(char* id){
	uint32_t hashcode=0;
	while(*(id)!='\0'){
		hashcode+=*(id);
		id++;
	}
	return (uint32_t)(hashcode%SIZE);
}
void insert_stu(hash_t* hashtable){
	datatype_t* stu=(datatype_t*)malloc(sizeof(datatype_t));
	if(stu==NULL){
		printf("malloc failure\n");
	}
	printf("请输入:【学号,姓名,性别,年龄,分数】");
	scanf("%s %s %s %d %f",stu->id,stu->name,stu->gender,&(stu->age),&(stu->score));
	uint32_t res=get_hashindex(stu->id);
	linkedlist_insert_head(hashtable->item[res],stu);
	if(res){
		printf("添加成功\n");
	}else{
		printf("添加失败\n");
	}
}

void show_stus(hash_t* p_hashtable){
	printf("------------------学生信息如下----------------------\n");
	printf("\tID\t姓名\t性别\t年龄\t成绩\t\n");
	for(int i=0;i<SIZE;i++){
		linkedlist_show(*(p_hashtable->item+i));
	}
	printf("----------------------------------------------------\n");
}

void search_stu_by_id(hash_t* hashtable){
	printf("请输入学号:");
	char id[128]={0};
	while(getchar()!='\n');
	fgets(id,sizeof(id)-1,stdin);
	id[strlen(id)-1]='\0';
	uint32_t index=get_hashindex(id);
	search_data(hashtable->item[index],id);
}

void del_stu_by_id(hash_t* hashtable){
	printf("请输入要删除的学生的学号:");
	char id[128]={0};
	while(getchar()!='\n');
	fgets(id,sizeof(id)-1,stdin);
	id[strlen(id)-1]='\0';
	uint32_t index=get_hashindex(id);
	bool res=linkedlist_remove_data(hashtable->item[index],id);
	if(res){
		printf("删除成功!\n");
	}else{
		printf("查无此人\n");
	}
	
}
void modify_stu_by_id(hash_t* hashtable){
	printf("请输入修改学生的ID:");
	char id[128]={0};
	while(getchar()!='\n');
	fgets(id,sizeof(id)-1,stdin);
	id[strlen(id)-1]='\0';
	//根据ID获取哈希索引
	uint32_t index=get_hashindex(id);
	datatype_t* data=linkedlist_modify_stu(hashtable->item[index],id);
	if(data!=NULL){
		printf("修改学生信息成功");
		printf("ID\t姓名\t性别\t年龄\t成绩\t\n");
		printf("%s\t%s\t%s\t%d\t%.2f\t\n",data->id,data->name,data->gender,data->age,data->score);
	}else{
		printf("该%s对应学生不存在,修改学生信息失败\n",id);
	}
}

void clear_hashtable(hash_t**p_hashtable){
	linkednode_t** arr=(*p_hashtable)->item;
	for(int i=0;i<SIZE;i++){
		linkedlist_clear(*(arr+i));
	}
	free(*p_hashtable);
	p_hashtable=NULL;
}
        management.h
#ifndef __HEAD_MANAGEMENT_H__
#define __HEAD_MANAGEMENT_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <stdbool.h>
#include "linkedlist.h"

#define SIZE 13

typedef struct{
	char id[128];
	char name[128];
	char gender[64];
	uint32_t age;
	float score;
}datatype_t;

typedef struct Node{
	datatype_t* data;
	struct Node* next;
}linkednode_t;


typedef struct {
	linkednode_t* item[SIZE];
	int n;
}hash_t;

//  登录状态
extern bool login_status;
extern void login();
extern void create_hashtable(hash_t**);
// 创建hash函数
extern uint32_t get_hashIndex(char*);
extern void insert_stu(hash_t*);
extern void show_stus(hash_t*);
extern void show_stus_linkedlist(hash_t*);
extern void search_stu_by_id(hash_t*);
extern void del_stu_by_id(hash_t*);
extern void modify_stu_by_id(hash_t*);
extern void clear_hashtable(hash_t**);
#endif
        linkedlist.c
#include "linkedlist.h"

void linkedlist_init(linkednode_t** p_dummyhead){                                         
        linkednode_t* p_node = (linkednode_t*)malloc(sizeof(linkednode_t));        
        if(p_node==NULL){                                        
                printf("malloc failure:%s\n",strerror(errno));   
                return;                                    
        }                                                        
        memset(p_node,0,sizeof(linkednode_t));                                                              
        p_node->next = NULL; 
	*p_dummyhead = p_node;	
}

// 添加的方法
bool linkedlist_insert_head(linkednode_t* p_dummyhead,datatype_t* p_data){
	//将data添加到链表的尾部
	// 1、封装成节点
	linkednode_t* p_node = (linkednode_t*)malloc(sizeof(linkednode_t));
	if(p_node==NULL){
		printf("malloc failure:%s\n",strerror(errno));
		return false;
	}
	memset(p_node,0,sizeof(linkednode_t));
	p_node->data = p_data;
	p_node->next = NULL;
	
	// 进行挂接
	p_node->next = p_dummyhead->next;
	p_dummyhead->next = p_node;
	return true;
}

bool linkedlist_is_empty(linkednode_t* p_dummyhead){
	return p_dummyhead == NULL || p_dummyhead->next==NULL;
}

bool linkedlist_remove_data(linkednode_t* p_dummyhead,const char* id){
	if(linkedlist_is_empty(p_dummyhead)){
		return false;
	}else{
		// 查找数据是否存在
		linkednode_t* pre = p_dummyhead;
		while(pre->next!=NULL){
			if(strcmp(id,pre->next->data->id)==0){
				linkednode_t* delnode = pre->next;
				pre->next = pre->next->next;
				free(delnode);
				delnode=NULL;
				return true;
			}
			pre=pre->next;
		}	
		return false;
	}
}

void linkedlist_show(linkednode_t* p_dummyhead){
	linkednode_t* cur=p_dummyhead->next;
	while(cur!=NULL){
		printf("\t%s\t%s\t%s\t%d\t%.2f\n",cur->data->id,cur->data->name,cur->data->gender,cur->data->age,cur->data->score);
	cur= cur->next;
	}
}
void linkedlist_display(linkednode_t* p_dummyhead){
	linkednode_t* cur= p_dummyhead->next;
	while(cur!=NULL){
		printf("%s--->",cur->data->id);
		cur=cur->next;
	}
	printf("NULL\n");
}

void search_data(linkednode_t* dummyhead,const char* id){
	if(dummyhead->next==NULL){
		printf("查无此人!\n");
		return;
	}
	linkednode_t* cur=dummyhead->next;
	while(cur != NULL){
		if(strcmp(cur->data->id,id) == 0){
			printf("ID\t姓名\t性别\t年龄\t成绩\t\n");
			printf("%-8s%-8s%-8s%-4d%-4f\n",cur->data->id,cur->data->name,cur->data->gender,cur->data->age,cur->data->score);
			return;
		}
		cur = cur->next;
	}
	if(cur == NULL){
		printf("找不到此人\n");
		return;
	}
}


datatype_t* linkedlist_modify_stu(linkednode_t* p_dummyhead,const char* id){
	linkednode_t* cur=p_dummyhead->next;
	while(cur!=NULL){
		if(strcmp(cur->data->id,id)==0){
			printf("---------------修改学生信息------------------\n");
			printf("\t1.姓名\n");
			printf("\t2.性别\n");
			printf("\t3.年龄\n");
			printf("\t4.分数\n");
			printf("\t0.退出\n");
			printf("请选择:");
			int select;
			datatype_t* stu=cur->data;
			scanf("%d",&select);
			switch(select){
				case 1:
					while(getchar()!='\n');
					printf("姓名:");
					fgets(stu->name,sizeof(stu->name)-1,stdin);
					stu->name[strlen(stu->name)-1]='\0';
					break;
				case 2:
					while(getchar()!='\n');
                                        printf("性别:");
                                        fgets(stu->gender,sizeof(stu->gender)-1,stdin);
                                        stu->gender[strlen(stu->gender)-1]='\0';
                                        break;
				case 3:
					printf("年龄:");
					scanf("%d",&(stu->age));
					break;
				case 4:
                                        printf("成绩:");
                                        scanf("%f",&(stu->score));
                                        break;
				case 0:
					break;
			}
			return stu;
		}
		cur=cur->next;
	}
	return NULL;
}

void linkedlist_clear(linkednode_t* p_dummyhead){
	linkednode_t* pre=p_dummyhead;
	while(pre->next!=NULL){
		linkednode_t* del=pre->next;
		pre->next=pre->next->next;
		free(del);
		del=NULL;
	}
	free(p_dummyhead);
	p_dummyhead=NULL;
}
        linkedlist.h

        

#ifndef __HEAD_LINKED_LIST_H__
#define __HEAD_LINKED_LIST_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#in#clude <stdbool.h>
#include <errno.h>
#include "management.h"

extern bool linkedlist_insert_head(linkednode_t*, datatype_t*);
extern void linkedlist_init(linkednode_t**);
extern bool linkedlist_is_empty(linkednode_t*);
extern bool linkedlist_remove_data(linkednode_t*,const char*);
extern void linkedlist_show(linkednode_t*);
extern void linkedlist_display(linkednode_t*);
extern void search_data(linkednode_t*,const char*);
extern void del_data(linkednode_t*,const char*);
extern datatype_t*linkedlist_modify_stu(linkednode_t*,const char*);
extern void linkedlist_clear(linkednode_t*);
#endif
输出结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C# WPF】Style全局样式和资源字典

1.全局样式&#xff1a; 在Window.Resource中声明一个样式&#xff0c;总体为白色&#xff0c;为了更有区分度&#xff0c;采用BasedOn这一继承方式来在保留字体和边缘设置的基础上&#xff0c;更改颜色。 <Window x:Class"WpfApp1.Window1"xmlns"http://s…

LangChain 推出 LangGraph Studio:首款用于可视化、交互和调试复杂代理应用的代理 IDE

嘿&#xff0c;听说了吗&#xff1f;Langchain最近发布了一项重大更新&#xff0c;他们推出了官方Agent IDE&#xff0c;并且免费开放了LangGraph平台。这对于AI开发者来说是个好消息&#xff0c;意味着我们现在有了更强大的工具来构建智能应用。 今天&#xff0c;我们就来分享…

CI/CD——CI持续集成实验

目录 一. 安装Docker 二. 部署Jenkins 三. 配置邮箱 四. Harbor部署 五. Nexus Repository部署 五. sonarqube安装 六. 配置Docker 七. jenkins系统配置sonarqube 八. 配置pipeline 九. 构建并集成 一. 安装Docker docker-ce镜像_docker-ce下载地址_docker-ce安装教程…

HTTP、HTTPS、SOCKS5 三种协议特点详解

一、引言 在当今数字化的世界中&#xff0c;网络通信协议扮演着至关重要的角色。HTTP、HTTPS 和 SOCKS5 是三种常见的网络协议&#xff0c;它们各自具有独特的特点和应用场景。本文将对这三种协议进行详细的分析和比较&#xff0c;帮助您更好地理解它们在网络通信中的作用。 …

vue2+OpenLayers 天地图上打点并且显示相关的信息(2)

上次是在地图上打点 这次鼠标移动在图标上面显示相关的信息 首先有两个事件 鼠标移入 和 鼠标移出事件 pointermove pointerout 鼠标放上去之前 放上去后 代码如下 <template><div class"container"><div id"vue-openlayers" class&quo…

多模态大语言模型(MMLLM)的现状、发展和潜力

1、大模型 随着ChatGPT流行&#xff0c;大模型技术正逐渐成为AI领域的热点。许多行业大佬纷纷投身于这一赛道&#xff0c;展示了大模型的独特魅力和广阔前景。 王慧文&#xff0c;前美团联合创始人&#xff0c;发起“AI英雄帖”。 李志飞&#xff0c;出门问问创始人&#xff0…

7个Agent组成的公司,7分钟完成了一个游戏的开发

来源丨投资实习所&#xff08;ID&#xff1a;startupboy&#xff09; 作者丨StartupBoy 市场对 AI Agent 的期望一直很高&#xff0c;除了各种单向任务的 Agent 外&#xff0c;之前斯坦福大学和 Google 的一项实验已经展示了由 25 个 AI Agent 自行协同运行的虚拟城镇&#x…

如何使用Zoom API创建一个会议?

一、注册一个免费的Zoom账号&#xff08;zoom.us) 二、在Zoom 应用市场&#xff08;App Marketplace)创建一个server to server 的app&#xff0c;授予创建会议的权限。 三、创建一个Zoom API的服务端程序(node.js) 1、git clone https://github.com/zoom/server-to-server-o…

Unity新输入系统 之 InputActions(输入配置文件)

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​ 首先你应该了解新输入系统的基本单位Unity新输入系统 之 InputAction&#xff08;输入配置文件最基本的单位&#xff0…

Python-调用pymysql库,执行插入语句

今天写了一个mysql的插入方法&#xff0c;传多条数据时报错: TypeError: not enough arguments for format string 解决:后来排查是因为调用方法是&#xff0c;用的cursor.excute()&#xff0c;导致的报错&#xff0c;改为cursor.excutemany()就插入成功了 方法调用: test.ins…

【ARM CoreLink 系列 5.5 -- CI-700 Debug trace and PMU 】

文章目录 Debug trace and PMUCI-700 Debug trace 系统概述DTC DomainDTC Domain 约束条件DTM device portsDTM FIFO BufferDTM FIFO 缓冲区特点Debug trace and PMU 本篇文章主要是介绍 CI-700中实现的 Debug Trace (DT) and Performance Monitoring Unit (PMU). CI-700 Deb…

漏洞复现-Viessmann Vitogate 远程命令执行漏洞(CVE-2023-45852)

1.漏洞描述 Viessmann Vitogate是Viessmann公司的一个智能化控制系统。 Vitogate 300 2.1.3.0版本的/cgi-bin/vitogate.cgi存在一个未经身份验证的攻击者可利用的漏洞&#xff0c;通过put方法中的ipaddr params JSON数据中的shell元字符实现绕过身份验证并执行任意命令。 2.…

c++_1

C 定义头文件 #ifndef __COMPLEX__ // 这样定义头文件&#xff0c;可以解决有些cpp在包含头文件需要的次序要求&#xff1b;也不会有重复的定义头文件 #define __COMPLEX__#endif#pragma once 是 C 预处理器指令&#xff0c;用于防止头文件被多次包含&#xff0c;从而避免头文…

C++解析和构建json(cjson使用手册)

C解析和构建json【cjson使用手册】 一、cjson下载二、cjson工程使用2.1 静态库使用2.1 源码使用&#xff08;推荐&#xff09; 三、cjson详解3.1 解析json字符串3.1.1 解析对象3.1.2 解析数组&#xff1a;方法一&#xff08;获取列表数量然后按照位置获取&#xff09;3.1.2 解析…

从专家角度看:2024年值得关注的项目文档工具

国内外主流的10款项目文档管理软件对比&#xff1a;PingCode、Worktile、禅道、Tower、飞书、Smartsheet、Jira、Notion、Wrike、Basecamp。 在项目管理的世界里&#xff0c;选择一个合适的文档管理工具可能就是成功与否的关键。众多的系统和功能看似琳琅满目&#xff0c;但这也…

无字母数字绕过正则表达式

目录 1、题目代码 1.异或 php部分&#xff1a; python代码&#xff1a; 2.或 php代码 python代码 测试结果&#xff1a; 3、取反 php脚本&#xff1a; 测试结果&#xff1a; 1、题目代码 <?php error_reporting(0); highlight_file(__FILE__); $code$_GET[code…

速度曲线轨迹规划程序优化(封装FC)

1、S型速度曲线点动控制功能块 S型速度曲线点动控制功能块(博途SCL代码)-CSDN博客文章浏览阅读16次。点动功能块只有4个约束条件。https://rxxw-control.blog.csdn.net/article/details/139657487 2、梯形速度曲线绝对值定位功能块 梯形速度曲线绝对值定位功能块(博途SCL代码…

设计模式六大原则之:单一职责原则

1. 单一职责简介 设计模式中的单一职责原则&#xff08;‌Single Responsibility Principle, SRP&#xff09;‌是面向对象设计中的一个基本原则&#xff0c;‌它强调一个类应该仅有一个引起它变化的原因。‌换句话说&#xff0c;‌一个类应该负责一组相对独立且紧密相关的职责…

VisionPro二次开发学习笔记13-使用CogToolBlock进行图像交互

该程序演示了如何使用CogToolBlock进行图像交互. 从vpp文件中加载一个ToolBlock。 用户可以通过应用程序窗体上的数字增减控件修改ToolBlock输入端子的值。 用户还可以从coins.idb或采集FIFO中选择图像。 “运行一次”按钮执行以下操作&#xff1a; 获取下一个图像或读取下一…

数学建模学习笔记

数学建模学习笔记 现学现卖&#xff0c;随缘更新QwQ 主要根据b站大师兄的视频整理而成&#xff0c;有不懂的可以去看原视频 List 数学建模学习笔记一、 层次分析法1.1 矩阵的一致性及其检验1.2 权重计算1.3 具体流程 二、模糊综合评测2.1 隶属函数2.2 隶属函数的确定方法2.3 模…