연습 코드3
// Practice3
// 해시 충돌 해결 - 개방 주소법 (제곱 탐사법)
class MyHashTable3 extends MyHashTable {
MyHashTable3(int size) {
super(size);
}
public void setValue(int key, int data) {
int idx = this.getHash(key);
if(this.elemCnt == this.table.length) {
System.out.println("Hash table is full!");
return;
} else if (this.table[idx] == null) {
this.table[idx] = data;
} else {
// 충돌 - 제곱 탐사법
int newIdx = idx; // 충돌 난 지점으로 초기화 시켜놓고
int cnt = 0; // 충돌이 몇번 발생하는지 카운트
while (true) {
// 2의 제곱수를 table.length로 나눈 나머지
newIdx = (newIdx + (int)Math.pow(2, cnt)) % this.table.length;
if (this.table[newIdx] == null) {
break;
}
cnt++;
}
this.table[newIdx] = data;
}
this.elemCnt++;
}
}
public class Practice3 {
public static void main(String[] args) {
// Test code
MyHashTable3 ht = new MyHashTable3(11);
ht.setValue(1, 10);
ht.setValue(2, 20);
ht.setValue(4, 40);
ht.printHashTable();
ht.setValue(1, 100);
ht.printHashTable();
ht.setValue(1, 200);
ht.setValue(1, 300);
ht.setValue(1, 400);
ht.printHashTable();
}
}
연습 코드4
// Practice4
// 해시 충돌 해결 - 개방 주소법 (이중 해싱)
class MyHashTable4 extends MyHashTable {
int c;
MyHashTable4(int size) {
super(size);
this.c = this.getHashC(size);
}
public int getHashC(int size) {
int c = 0;
// 소수
if (size <= 2) {
return size;
}
for (int i = size - 1; i > 2; i--) {
boolean isPrime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
c = i;
break;
}
}
return c;
}
// 두 번째 해시함수를 구하기 위한 메소드
public int getHash2(int key) {
int hash = 1 + key % this.c; // 이중 해싱의 기본적인 형태라고 보면 됨
return hash;
}
public void setValue(int key, int data) {
int idx = this.getHash(key);
if (this.elemCnt == this.table.length) {
System.out.println("Hash table is full!");
return;
} else if (this.table[idx] == null) {
this.table[idx] = data;
} else { // 충돌
int newIdx = idx;
int cnt = 1;
while (true) {
newIdx = (newIdx + this.getHash2(newIdx) * cnt) % this.table.length;
if (this.table[newIdx] == null) {
break;
}
cnt++;
}
this.table[newIdx] = data;
}
this.elemCnt++;
}
}
public class Practice4 {
public static void main(String[] args) {
// Test code
MyHashTable4 ht = new MyHashTable4(11);
ht.setValue(1, 10);
ht.setValue(2, 20);
ht.setValue(3, 30);
ht.printHashTable();
ht.setValue(1, 100);
ht.setValue(1, 200);
ht.setValue(1, 300);
ht.printHashTable();
}
}
연습 코드5
// Practice5
// 해시 충돌 해결 - 분리 연결법
class Node {
int key;
int data;
Node next;
Node() {}
Node(int key, int data, Node next) {
this.key = key;
this.data = data;
this.next = next;
}
}
class LinkedList {
Node head;
LinkedList() {}
LinkedList(Node node) {
this.head = node;
}
public boolean isEmpty() {
return this.head == null;
}
public void addData(int key, int data) {
if (this.head == null) {
this.head = new Node(key, data, null);
} else {
Node cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = new Node(key, data, null);
}
}
public void removeData(int data) {
if (this.isEmpty()) {
System.out.println("List is empty");
return;
}
Node cur = this.head;
Node pre = cur;
while (cur != null) {
if (cur.key == data) {
if (cur == this.head) {
this.head = cur.next;
} else {
pre.next = cur.next;
}
break;
}
pre = cur;
cur = cur.next;
}
}
public Integer findData(int data) {
if (this.isEmpty()) {
System.out.println("List is empty");
return null;
}
Node cur = this.head;
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;
}
public void showData() {
if (this.isEmpty()) {
System.out.println("List is empty!");
return;
}
Node cur = this.head;
while (cur != null) {
System.out.print(cur.data + " ");
cur = cur.next;
}
System.out.println();
}
}
class MyHashTable5 {
LinkedList[] table;
MyHashTable5(int size) {
this.table = new LinkedList[size];
for (int i = 0; i < this.table.length; i++) {
this.table[i] = new LinkedList(null);
}
}
public int getHash(int key) {
return key % this.table.length;
}
public void setValue(int key, int data) {
int idx = this.getHash(key);
this.table[idx].addData(key, data);
}
public int getValue(int key) {
int idx = this.getHash(key);
int data = this.table[idx].findData(key);
return data;
}
public void removeValue(int key) {
int idx = this.getHash(key);
this.table[idx].removeData(key);
}
public 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 class Practice5 {
public static void main(String[] args) {
// Test code
MyHashTable5 ht = new MyHashTable5(11);
ht.setValue(1, 10);
ht.setValue(2, 20);
ht.setValue(3, 30);
ht.printHashTable();
ht.setValue(12, 11);
ht.setValue(23, 12);
ht.setValue(34, 13);
ht.setValue(13, 21);
ht.setValue(24, 22);
ht.setValue(35, 23);
ht.setValue(5, 1);
ht.setValue(16, 2);
ht.setValue(27, 3);
ht.printHashTable();
System.out.println("== key 값으로 해당 데이터 가져오기 ==");
System.out.println(ht.getValue(1));
System.out.println(ht.getValue(12));
System.out.println("== 데이터 삭제 ==");
ht.removeValue(1);
ht.removeValue(5);
ht.removeValue(16);
ht.printHashTable();
}
}