키 : 해시 테이블 접근을 위한 입력 값
해시 함수 : 키를 해시 값으로 매핑하는 연산
해시 값 : 해시 테이블의 인덱스
해시 테이블 : 키-값을 연관시켜 저장하는 데이터 구조
static int getHash(int key) {
return key%5;
}
public static void main(String[] args) {
Hashtable<Integer, Integer> ht2 = new Hashtable<>();
ht2.put(getHash(1), 10);
ht2.put(getHash(2), 20);
ht2.put(getHash(3), 30);
ht2.put(getHash(4), 40);
ht2.put(getHash(5), 50);
System.out.println("== 충돌 전 ==");
for (Map.Entry<Integer, Integer> item : ht2.entrySet()) {
System.out.println(item.getKey()+" - "+item.getValue());
}
System.out.println("== 충돌 후 ==");
ht2.put(getHash(6), 60);
for (Map.Entry<Integer, Integer> item : ht2.entrySet()) {
System.out.println(item.getKey()+" - "+item.getValue());
}
// 1 - 10 -> 1 - 60 으로 데이터 값이 수정됨
}
개방 주소법
// 선형 탐사법
static int getHash(int key, int n) {
return ((key % n) + n) % n;
}
public static void main(String[] args) {
Hashtable<Integer, Integer> ht2 = new Hashtable<>();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(ht2.size()<n) {
int key = getHash(sc.nextInt(), n);
int value = sc.nextInt();
while(ht2.containsKey(key)) {
key++;
}
ht2.put(getHash(key, n), value);
}
for (Integer i : ht2.keySet()) {
System.out.println(i+" - "+ht2.get(i));
}
}
// 제곱 탐사법
public static void main(String[] args) {
Hashtable<Integer, Integer> ht2 = new Hashtable<>();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(ht2.size()<n) {
int key = getHash(sc.nextInt(), n);
int value = sc.nextInt();
int cnt=0;
while(ht2.containsKey(key)) {
key = getHash(key+(int)Math.pow(2, cnt), n);
cnt++;
}
ht2.put(key, value);
}
for (Integer i : ht2.keySet()) {
System.out.println(i+" - "+ht2.get(i));
}
}
// 이중 해싱
static int getHash2(int key, int n) {
return 1 + (key % (n - 1));
}
public static void main(String[] args) {
Hashtable<Integer, Integer> ht2 = new Hashtable<>();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while (ht2.size() < n) {
int originalKey = sc.nextInt();
int value = sc.nextInt();
int key = getHash(originalKey, n);
int step = getHash2(originalKey, n);
int cnt = 0;
while (ht2.containsKey(key)) {
key = getHash(originalKey + step * cnt, n);
cnt++;
}
ht2.put(key, value);
}
for (Integer i : ht2.keySet()) {
System.out.println(i + " - " + ht2.get(i));
}
}
분리 연결법
static class Node {
int key, data;
Node next;
Node() {}
public Node(int key, int data, Node next) {
this.key = key;
this.data = data;
this.next = next;
}
}
static class LinkedList {
Node root;
LinkedList() {}
LinkedList(Node node) { this.root = node; }
boolean isEmpty() { return this.root == null; }
void addData(int key, int data) {
if(this.root==null) this.root = new Node(key, data, null);
else {
Node cur = this.root;
while (cur.next!=null) {
cur = cur.next;
}
cur.next = new Node(key, data, null);
}
}
void removeData(int data) {
if(this.isEmpty()) {
System.out.println("List is empty");
return;
}
Node cur = this.root;
Node pre = cur;
while (cur!=null) {
if (cur.key==data) {
if (cur == this.root) this.root = cur.next;
else pre.next = cur.next;
break;
}
pre = cur;
cur = cur.next;
}
}
Integer findData(int data) {
if(this.isEmpty()) {
System.out.println("List is empty");
return null;
}
Node cur = this.root;
while (cur!=null) {
if (cur.key==data) {
System.out.println("Data exist!");
return cur.data;
}
cur = cur.next;
}
System.out.println("Data not found!");
return null;
}
void showData() {
if (this.isEmpty()) {
System.out.println("List is empty!");
return;
}
Node cur = this.root;
while (cur!=null) {
System.out.print(cur.data+" ");
cur = cur.next;
}
System.out.println();
}
}
static class MyHashTable {
LinkedList[] table;
MyHashTable(int size) {
this.table = new LinkedList[size];
for (int i = 0; i < this.table.length; i++) {
this.table[i] = new LinkedList(null);
}
}
int getHash(int key) {
return key%this.table.length;
}
void setValue(int key, int data) {
int idx = this.getHash(key);
this.table[idx].addData(key, data);
}
int getValue(int key) {
int idx = this.getHash(key);
return this.table[idx].findData(key);
}
void removeValue(int key) {
int idx = this.getHash(key);
this.table[idx].removeData(key);
}
void printHashTable() {
System.out.println("== Hash Table ==");
for (int i = 0; i < this.table.length; i++) {
System.out.print(i+" : ");
this.table[i].showData();
}
}
}
public static void main(String[] args) {
MyHashTable ht = new MyHashTable(11);
ht.setValue(1, 10); // 1 : 10
ht.setValue(2, 20); // 2 : 20
ht.setValue(3, 30); // 3 : 30
ht.printHashTable();
ht.setValue(12, 11); // 1 : 10 11
ht.setValue(23, 12); // 1 : 10 11 12
ht.setValue(34, 13); // 1 : 10 11 12 13
ht.setValue(13, 21); // 2 : 20 21
ht.setValue(24, 22); // 2 : 20 21 22
ht.setValue(35, 23); // 2 : 20 21 22 23
ht.setValue(5, 1); // 5 : 1
ht.setValue(16, 2); // 5 : 1 2
ht.setValue(27, 3); // 5 : 1 2 3
ht.printHashTable();
System.out.println("== key 값으로 해당 데이터 가져오기 ==");
System.out.println(ht.getValue(1)); // 10
System.out.println(ht.getValue(12)); // 11
System.out.println("== 데이터 삭제 ==");
ht.removeValue(1); // 1 : 11 12 13
ht.removeValue(5); // 5 : 2 3
ht.removeValue(16); // 5 : 3
ht.printHashTable();
}