go手动实现哈希表

7 篇文章 0 订阅
1 篇文章 0 订阅

go手动实现哈希表

原理作用

哈希表的作用就是将一个较大范围或者较复杂的数据映射到一个较小的数据(0~N)

哈希算法

1、取模,x % y ,y一般取值为质数,并且要尽可能的离2的整次幂远,这样取值,发生冲突的概率最小

2、解决冲突,通常有两种方法,拉链法和开放寻址法

方法

题目:
维护一个集合,支持如下几种操作:

“I x”,插入一个数x;
“Q x”,询问数x是否在集合中出现过;
现在要进行N次操作,对于每个询问操作输出对应的结果。

输入格式
第一行包含整数N,表示操作数量。

接下来N行,每行包含一个操作指令,操作指令为”I x”,”Q x”中的一种。

输出格式
对于每个询问指令“Q x”,输出一个询问结果,如果x在集合中出现过,则输出“Yes”,否则输出“No”。

每个结果占一行。

数据范围
1≤N≤105
−109≤x≤109
输入样例:
5
I 1
I 2
I 3
Q 2
Q 5
输出样例:
Yes
No
*/
1、拉链法
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const N = 100003

var (
	idx int
	h   [N]int
	ne  [N]int
	e   [N]int
)
// 求质数
func primeNumber(i int) {
	var tag bool
	for {
		for j := 2; j*j < i; j++ {
			tag = true
			if i%j == 0 {
				tag = false
				break
			}
		}
		if tag {
			fmt.Println(i)
			break
		}
		i++
	}
}
func insert(x int) {
	k := (x%N + N) % N
	e[idx] = x
	ne[idx] = h[k]
	h[k] = idx
	idx++
}
func find(x int) {
	k := (x%N + N) % N
	// 遍历链表,找到上面与x相等的值
	for i := h[k]; i != -1; i = ne[i] {
		if e[i] == x {
			fmt.Println("Yes")
			return
		}
	}
	fmt.Println("No")

}

func readline(r *bufio.Reader) []string {
	s, _ := r.ReadString('\n')
	ss := strings.Fields(s)

	return ss
}
func main() {
	//将哈希表的初始值设置为-1
	for i := 0; i < N; i++ {
		h[i] = -1
	}
	var n int
	fmt.Scanf("%d", &n)

	r := bufio.NewReader(os.Stdin)
	for i := 0; i < n; i++ {
		in := readline(r)
		op := in[0]
		switch op {
		case "I":
			x, _ := strconv.Atoi(in[1])
			insert(x)
		case "Q":
			x, _ := strconv.Atoi(in[1])
			find(x)
		}
	}
}



2、开放寻址法
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

//const N  = 100003
const N  = 200003 // 大概是需要的2-3倍
const null = 0x3f3f3f3f
var h[N]int

func find(x int)int {
	k := (x%N + N) % N
	for h[k]!=null && h[k]!=x{ // 说明该位置已经被占用了
		k++ // 向后一位移动
		if k==N{ // 如果看完最后一个位置,
			k=0 //循环看第一个位置
		}
	}
	//h[k]=x
	return k // 返回下标,如果x在哈希数组h中,就返回x在h中的位置,
			// 如果不在,就返回应该存储的位置
}
func insert(x int)  {
	//k := (x%N + N) % N
	//for h[k]!=null{ // 说明该位置已经被占用了
	//	k++ // 向后一位移动
	//}
	k :=find(x)
	h[k]=x
}
func query(x int)  {
	k :=find(x)
	if h[k]!=null{
		fmt.Println("Yes")
	}else {
		fmt.Println("No")
	}
}
func readLine(r *bufio.Reader)[]string  {
	s,_ :=r.ReadString('\n')
	sSlcie:=strings.Fields(s)
	return sSlcie
}
func main() {
	for i:=0;i<N;i++{
		h[i] = null
	}
	var n int
	fmt.Scan(&n)

	r :=bufio.NewReader(os.Stdin)
	for i:=0;i<n;i++{
		in :=readLine(r)
		op :=in[0]
		x,_ :=strconv.Atoi(in[1])
		k :=find(x)
		switch op {
		case "I":
			//insert(x)
			h[k] = x
		case "Q":
			//x,_ :=strconv.Atoi(in[1])
			//query(x)
			if h[k] == null{
				fmt.Println("No")
			}else {
				fmt.Println("Yes")
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值