01.6哈希表

哈希表(Hash table)是一种根据关键码值直接访问的数据结构,通过散列函数将关键码映射到表中的位置,加快查找速度。本文介绍了哈希表的基本概念,包括其在增删改查操作中的应用,并提供了相关链接进行深入学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哈希表(Hash table)(散列表)

  • 散列表(Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中的一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放的數組叫做散列表。

    給定表M,存在函數f(key),對任意給定的關鍵字值key,帶入函數後若能得到包含該關鍵字的記錄在表中的地址,責成M為哈希表。函數f(key)為哈希函數。
    在这里插入图片描述

  • 實現增刪改查僱員的信息

    //僱員信息
    type Emp struct {
      Id int
    	Name string
    	Next *Emp
    }
    
    //僱員鏈錶從
    type EmpLink struct {
    	Head *Emp
    }
    
    //鏈錶插入操作
    func (this *EmpLink) Insert(emp *Emp) {
    	cur :=this.Head//輔助指針
    	var pre *Emp//輔助指針,cur之前
    	//不保留空的頭部,直接賦值
    	if cur == nil {
    		this.Head = emp
    		return
    	}
    	//如果需要替換頭結點
    	if cur.Id>emp.Id {
    		emp.Next = cur
    		this.Head = emp
    		return
    	}
    	for {
    		//如果沒到尾部繼續循環
    		if cur != nil {
    			//如果當前ID大於傳入的僱員ID
    			//就可以退出循環,在此位置添加
    			if cur.Id>emp.Id{
    				break
    			}
    			if cur.Id == emp.Id {
    				fmt.Println("不可插入相同的ID!")
    				return
    			}
    			pre = cur
    			cur = cur.Next
    		}else {
    			//如果當前為nil,即循環到尾部
    			//將最大的ID僱員添加在尾部
    			break
    		}
    	}
    	pre.Next = emp
    	emp.Next = cur
    }
    //鏈錶查找操作,更新操作可複用
    func (this *EmpLink) Find(id int) *Emp{
    	cur := this.Head
    	if cur == nil {
    		fmt.Println("所查鏈錶為空鏈錶")
    		return nil
    	}
    	for {
    		if cur.Id == id {
    			fmt.Printf("已找到id=%d,name=%s",id,cur.Name)
    			fmt.Println()
    			return cur
    		}
    		//順序儲存不會出現要查找的ID大於之前ID的情況
    		//只可能不存在
    		if cur.Id > id || cur.Next == nil{
    			fmt.Println("沒找到")
    			break
    		}
    		cur = cur.Next
    	}
    	return nil
    }
    //單鏈表刪除有點需要前結點,
    // 區別於查找,重新寫了一遍
    func (this *EmpLink)Del(id int)  {
    	cur := this.Head
    	var pre *Emp
    	if cur == nil {
    		fmt.Println("所刪鏈錶為空鏈錶")
    		return
    	}
    	//如果刪除的是頭結點
    	if cur.Id == id {
    		fmt.Printf("已刪除頭結點id=%d,name=%s",id,cur.Name)
    		fmt.Println()
    		this.Head = this.Head.Next
    		return
    	}
    	for {
    		pre = cur
    		cur = cur.Next
    		if cur.Id == id {
    			fmt.Printf("已刪除id=%d,name=%s",id,cur.Name)
    			fmt.Println()
    			pre.Next = cur.Next
    			return
    		}
    		if cur.Id > id || cur.Next == nil{
    			fmt.Println("沒找到")
    			break
    		}
    
    	}
    }
    //更新
    func (this *EmpLink)Update(emp *Emp,name string)  {
    	emp.Name = name
    	fmt.Printf("已更新id=%d,name=%s",emp.Id,emp.Name)
    	fmt.Println()
    }
    //顯示
    func (this *EmpLink) ShowLink(no int) {
    	if this.Head == nil {
    		fmt.Printf("鏈錶%d為空",no)
    		fmt.Println()
    		return
    	}
    	for {
    		if this.Head != nil {
    			fmt.Printf("鏈錶%d 僱員名字 id = %d 名字=%s ->",no,this.Head.Id,this.Head.Name)
    			this.Head = this.Head.Next
    		}else {
    			break
    		}
    	}
    	fmt.Println()
    }
    //哈希表,含有一個鏈錶數組
    type HashTable struct {
    	LinkArr [7]EmpLink
    }
    func (this *HashTable) Insert(emp *Emp) {
    	//使用散列函數,確定將僱員添加到哪個鏈錶
    	linkNo :=this.HashLink(emp.Id)
    	//使用對應的鏈錶添加
    	this.LinkArr[linkNo].Insert(emp)
    }
    func (this *HashTable)Find(id int)  {
    	findNo := id % 7
    	this.LinkArr[findNo].Find(id)
    }
    func (this *HashTable)Del(id int)  {
    	findNo := id % 7
    	this.LinkArr[findNo].Del(id)
    }
    func (this *HashTable) Update(id int, name string) {
    	findNo := id % 7
    	emp := this.LinkArr[findNo].Find(id)
    	this.LinkArr[findNo].Update(emp,name)
    }
    func (this *HashTable) ShowAll() {
    	for i := 0;i<len(this.LinkArr);i++{
    		this.LinkArr[i].ShowLink(i)
    		fmt.Println()
    	}
    }
    //對應於鏈錶
    func (this *HashTable) HashLink(id int) int {
    	return id%7
    }
    func main() {
    	key := ""
    	id := 0
    	name := ""
    	var hashtable HashTable
    	for {
    		fmt.Println("===========僱員菜單系統===========")
    		fmt.Println("input 表示添加員工")
    		fmt.Println("show 表示顯示員工")
    		fmt.Println("find 表示查找員工")
    		fmt.Println("delete 表示刪除員工")
    		fmt.Println("update 表示更新員工")
    		fmt.Println("exit 表示退出系統")
    		fmt.Println("請輸入指令")
    		fmt.Scanln(&key)
    		switch key {
    		case "input":
    			fmt.Println("輸入僱員id ")
    			fmt.Scanln(&id)
    			fmt.Println("輸入僱員name")
    			fmt.Scanln(&name)
    			emp := &Emp{
    				Id:id,
    				Name:name,
    			}
    			hashtable.Insert(emp)
    		case "show":
    			hashtable.ShowAll()
    		case "find":
    			fmt.Println("輸入僱員id ")
    			fmt.Scanln(&id)
    			fmt.Println(id)
    			hashtable.Find(id)
    		case "delete":
    			fmt.Println("輸入僱員id ")
    			fmt.Scanln(&id)
    			hashtable.Del(id)
    		case "update":
    			fmt.Println("輸入僱員id ")
    			fmt.Scanln(&id)
    			fmt.Println("輸入僱員new name")
    			fmt.Scanln(&name)
    			hashtable.Update(id,name)
    		case "exit":
    			os.Exit(0)
    		default:
    			fmt.Println("輸入錯誤")
    		}
    		fmt.Println()
    	}
    }
    
鏈接

资源下载链接为: https://pan.quark.cn/s/9e7ef05254f8 行列式是线性代数的核心概念,在求解线性方程组、分析矩阵特性以及几何计算中都极为关键。本教程将讲解如何用C++实现行列式的计算,重点在于如何输出分数形式的结果。 行列式定义如下:对于n阶方阵A=(a_ij),其行列式由主对角线元素的乘积,按行或列的奇偶性赋予正负号后求和得到,记作det(A)。例如,2×2矩阵的行列式为det(A)=a11×a22-a12×a21,而更高阶矩阵的行列式可通过Laplace展开或Sarrus规则递归计算。 在C++中实现行列式计算时,首先需定义矩阵类或结构体,用二维数组存储矩阵元素,并实现初始化、加法、乘法、转置等操作。为支持分数形式输出,需引入分数类,包含分子和分母两个整数,并提供与整数、浮点数的转换以及加、减、乘、除等运算。C++中可借助std::pair表示分数,或自定义结构体并重载运算符。 计算行列式的函数实现上,3×3及以下矩阵可直接按定义计算,更大矩阵可采用Laplace展开或高斯 - 约旦消元法。Laplace展开是沿某行或列展开,将矩阵分解为多个小矩阵的行列式乘积,再递归计算。在处理分数输出时,需注意避免无限循环和除零错误,如在分数运算前先约简,确保分子分母互质,且所有计算基于整数进行,最后再转为浮点数,以避免浮点数误差。 为提升代码可读性和可维护性,建议采用面向对象编程,将矩阵类和分数类封装,每个类有明确功能和接口,便于后续扩展如矩阵求逆、计算特征值等功能。 总结C++实现行列式计算的关键步骤:一是定义矩阵类和分数类;二是实现矩阵基本操作;三是设计行列式计算函数;四是用分数类处理精确计算;五是编写测试用例验证程序正确性。通过这些步骤,可构建一个高效准确的行列式计算程序,支持分数形式计算,为C++编程和线性代数应用奠定基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值