답변:
리프레셔로서 해시 테이블은 데이터 구조의 특정 키 아래에 값을 저장하는 방법입니다. 예를 들어, "a"
key 아래에 value 를 저장 1
한 다음 1
해시 테이블에서 키 를 찾아서 검색 할 수 있습니다.
내 머리 꼭대기에서 생각할 수있는 해시 테이블의 가장 간단한 예는 정수만 저장할 수있는 해시 테이블입니다. 여기서 해시 테이블 항목의 키도 저장되는 값입니다. 테이블의 크기가 8이며 기본적으로 메모리의 배열이라고 가정 해 봅시다.
---------------------------------
| | | | | | | | |
---------------------------------
0 1 2 3 4 5 6 7
해시 함수는 값을 저장할 위치에 대한 색인을 제공합니다. 이 테이블의 매우 간단한 해시 함수는 저장하려는 값에 1을 추가 한 다음 모드 8 (테이블 크기)하여. 즉, 해시 함수는입니다 (n+1)%8
. 여기서 n
저장하려는 정수입니다.
이 해시 테이블에 값을 삽입하려면 삽입하려는 값에 대해 해시 함수 (이 경우 (n+1)%8
) 를 호출하여 색인을 제공합니다. 예를 들어 14를 삽입하려면 (14 + 1) % 8
index를 호출 하여 index 7
에 값을 삽입합니다.7
.
---------------------------------
| | | | | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
마찬가지로 33, 82 및 191을 다음과 같이 삽입 할 수 있습니다.
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
그러나 항목과 충돌하는 것을 삽입하려고하면 어떻게됩니까? 2 인덱스로 이동3
하지만,이 문제를 해결하기 위해 여러 가지 방법이 있습니다 (82)에 의해 촬영, 간단한 우리가 빈 공간을 찾을 때까지 반복 또 다시 우리의 해시 함수를 호출하는 것입니다.
논리는 다음과 같습니다.
이제 해시 테이블은 다음과 같이 표시되며 값 2는 index에 저장됩니다 4
.
---------------------------------
|191| |33 |82 |2 | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
이 솔루션의 단점은 곧 테이블이 가득 찰 것입니다! 데이터 크기가 제한되어 있다는 것을 알고 있다면 테이블이 가능한 모든 값을 보유 할 수있을 정도로 큰 경우에는 문제가되지 않습니다. 더 많이 잡으려면 충돌을 다르게 처리 할 수 있습니다. 2를 삽입하기 전에 원래 위치로 되돌아 갑시다.
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
당신이 기억한다면, (2+1)%8
우리에게 index를 제공합니다 3
. 해시 테이블을 채우지 않으려면 각 테이블 인덱스를 연결된 목록으로 사용하고 해당 인덱스의 목록에 추가 할 수 있습니다. 따라서 해시 함수를 다시 호출하는 대신 index의 목록에 간단히 추가합니다 3
.
-----
| 2 |
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
이 목록은 메모리가 허용하는만큼 커질 수 있습니다. 18을 삽입 할 수 있으며 2에 추가됩니다.
-----
|18 |
-----
| 2 |
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
해시 테이블의 크기가 상당히 크면 해시 테이블의 값을 빠르게 찾을 수 있습니다. 해시 함수를 호출하고 색인을 얻으십시오. 82이 테이블에 있는지 확인하고 싶다고 가정 해 봅시다. lookup 함수는 (82+1)%8
=를 호출 3
하고 index의 항목을보고 3
반환합니다. 16을 조회하면 조회 기능이 색인에서 찾습니다.1
존재하지 않는지 확인합니다.
값 2를 찾으려고하면 해시 테이블은 데이터를 검색 할 때 데이터를 저장하는 데 사용한 것과 동일한 충돌 논리를 사용해야합니다. 해시 테이블의 작동 방식에 따라 원하는 항목을 찾을 때까지 (또는 공백을 찾을 때까지) 키를 계속 해시하거나 항목을 찾을 때까지 연결된 목록을 반복합니다 (또는 목록의 끝에 도착)
따라서 해시 테이블은 키-값 쌍을 빠르게 저장하고 액세스하는 좋은 방법입니다. 이 예에서는 값과 동일한 키를 사용했지만 실제 해시 테이블에서는 키가 그렇게 제한되지 않았습니다. 해시 함수는 키에서 작동하여 인덱스를 생성 한 다음 해당 인덱스에 키 / 값을 저장할 수 있습니다. 해시 테이블은 실제로 반복 될 수는 없지만 그렇게 할 수는 있습니다. 보시다시피, 해시 테이블은 많은 빈 공간을 가질 수 있으며,이를 반복하는 것은 시간 낭비입니다. 해시 테이블에 반복자에서 빈 공간 조회를 건너 뛰는 논리가 있더라도 링크 된 목록과 같이 반복 자용으로 설계된 데이터 구조를 사용하는 것이 더 적합합니다.
수천 권의 책이있는 도서관을 상상해보십시오. 제목별로 책을 최대한 빨리 찾을 수 있도록 책을 정리해야합니다.
이 작업을 수행하는 한 가지 일반적인 방법은 책을 사전 순으로 정렬하는 것입니다. 제목이 "G"로 시작하면 "G"영역을 찾은 다음 두 번째 문자를 찾아 "ö", "d", "e", "l", 검색 범위를 좁히십시오. 책을 찾을 때까지 그러나 새로운 책이 도착하면 새로운 도착을위한 공간을 마련하기 위해 레이아웃을 재구성해야 할 때가 있습니다.
이진 검색입니다. 좋아요
그러나이를 수행하는 더 빠른 방법이 있습니다. 모든 책장과 선반을 열거 한 다음 각 책마다 책을 찾을 수있는 책장 / 선반에 매핑되는 특별하고 희망적인 고유 번호를 계산한다고 가정 해 봅시다. "키"를 계산하는 방법은 무작위로 보이는 숫자를 제공하는 한 중요하지 않습니다. 예를 들어 제목에 모든 문자의 문자 코드를 추가 한 다음 소수로 나눌 수 있습니다 (가장 좋은 방법은 아니지만 어쨌든 작동합니다).
해싱입니다. 제목의 다음 글자를 찾는 전체 책장과 선반을 거치지 않아도되므로 훨씬 빠릅니다. 둘 이상의 책이 같은 키로 해석 될 때 "충돌"이 없으면 해싱은 일반적으로 원샷 작업입니다. 그러나 그것은 괜찮습니다. 해시 함수의 품질에 따라 같은 키 아래에 너무 많으면 안됩니다.
해시 테이블에는 몇 가지 제한 사항과 변덕 (재해 싱 / 크기 조정)이있어 바이너리 검색을 실행 가능한 경쟁자로 유지합니다. 어떤 방법이 더 나은지 흑백이 아닙니다. 그러나 그것은 다른 이야기입니다.
추신 : 귀하의 질문에 직접 대답하지 않아서 죄송합니다 (PHP로 해시 테이블 작성). 자세한 내용은 "programming";)
내가 아는 한 PHP의 해시 테이블은 단순히 다음을 통해 구현됩니다.
$my_hash = array(
1 => "Bob",
2 => "Alice",
3 => "Jack"
);
그런 다음 다음과 같은 호출을 통해 데이터에 액세스하십시오.
echo $my_hash[2]; // Will echo "Alice"
foreach () 함수를 사용하여 배열 내용을 반복합니다.
해시 테이블을 이해하는 가장 좋은 방법은 http://en.wikipedia.org/wiki/Hash_table 과 같은 것을 읽는 것입니다 . 그러나 대략 다음과 같이 요약됩니다. . 이 키는 해시 계산을 거치며 결과는 해시입니다. 이전에 MD5 또는 SHA 해시를 보았을 것입니다. 이와 매우 유사합니다. 이 해시의 특정 부분 (일반적으로 첫 번째 X 문자이지만 때로는 완전한 해시)은 값의 저장 영역 (오른쪽) 인 소위 '버킷'을 식별하는 데 사용됩니다.
그런 다음 해시 테이블에 액세스 할 때마다 키를 사용하여 값을 얻습니다. 키는 다시 해시로 계산되며 해시는 연결된 값을 빠르게 찾는 데 사용됩니다. 따라서 해시 테이블을 사용하면 모든 것이 저장된 경우 선형 검색보다 빠른 검색이 가능합니다. 유일한 단점은 일부 해시 구현에서 충돌이 발생한다는 것입니다. 이는 두 개의 다른 키에 대해 동일한 계산 된 해시입니다. 일반적으로 걱정할 필요는 없습니다.
나는 이것이 약간의 배경을 제공하기를 바랍니다. 내 설명은 매우 기초적이며 충분한 구멍이 있다고 확신하지만 빠른 설명을 위해서는 충분합니다.