해시 테이블 (Hash Table)


▷ 기본개념


1. 데이터를 담을 테이블을 미리 크게 확보해 놓는다.


2. 입력받은 데이터를 해시하여 테이블 내의 주소를 계산한다.


3. 나온 주소에 데이터를 담는다.


※ 

- 해시 테이블은 궁극의 탐색 알고리즘이다.

- 해시 테이블의 성능은 공간을 팔아 얻어낸 것이다.




▷ 특징


해시 테이블은 데이터가 입력되지 않은 여유 공간이 많아야 제 성능을 유지할 수 있다.


▷ 용어정리


1. 충돌 (Collision)


- 서로 다른 입력 값에 대해 동일한 해시 값.

- 해시 테이블 내의 동일한 주소를 반환 하는것.


※ 

- 알고리즘을 정교하게 설계한다고 해도 모든 입력값에 대해 고유한 값을 만들지 못한다.

=> 해시 함수의 충돌은 피할 수 없다는 것이다.



2. 클러스터(Cluster)


- 일부 지역의 주소들을 집중적으로 반환 하는 결과로 데이터들이 한 곳에 모이는 문제.



▷ 해쉬 테이블의 검색 성능.


- 해쉬 테이블의 검색성능은 해쉬 함수의 성능과 해쉬 테이블의 크기에 좌우된다.

- 충돌이 많이 발생하면 성능은 O(n)에 가까워지므로 충돌을 최대한 억제시키는 것이 해쉬의 핵심 포인트다.



▷ 해시(Hash)


- 자료를 입력할 때부터 검색하기 쉬운 위치에 삽입하는 방법이다.

- 해시는 검색 방법이라기보다는 빠른 검색을 위해 자료를 관리하는 기법이라고 보면 된다.


실 생활에서도 해시 기법은 흔히 사용된다.

수첩에 주소록을 작성할 때 '가나다'순으로 페이지를 미리 분류하고 이름의 첫 글자를 기준으로

주소를 적는 방법이 바로 해싱이다.


1. 해시 테이블(Hash Table) : 자료가 저장되는 전체 저장소.

2. 버킷(Bucket) : 주소록의 예에서 보면 ㄱ, ㄴ, ㄷ, ㄹ의 각 페이지가 버킷이다.

3. 슬롯(Slot) : 페이지를 버킷(Bucket)이라고 한다면 페이지에 주소를 기록하는 칸을 슬롯이라고 보면 된다.



4. 해시 함수 : 새로운 자료가 입력될 때 어떤 버킷에 넣을지를 결정하는 연산.




Code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
using namespace std;
 
 
#define KEY         10
#define CHAINING  3
 
int HashTable[KEY][CHAINING];
 
 
int Hash(int Key);
void AddKey(int Key);
bool FindKey(int Key);
void main()
{
    memset( HashTable, 0, sizeof(HashTable));
 
    // 데이터 입력
    int Key = 0;
    for(int i = 0; i < 5; i++)
    {
        printf("[%d]번째 입력: ",i + 1);
        scanf("%d", &Key);
        AddKey(Key);
    }
 
    printf("\n");
 
    // 데이터 탐색.
    printf("찾을 데이터를 입력:");
    scanf("%d", &Key);
    FindKey(Key);
 
    printf("\n");
 
    // 테이블 내에 데이터 출력.
    for(int i = 0; i < KEY; i++)
    {
        for(int j = 0; j < CHAINING; j++)
            printf("[%d]번째 : %d",i + 1, HashTable[i][j]);
        printf("\n");
    }
}
 
// 해싱.
int Hash(int Key)
{
    return Key % 100;
}
 
// 데이터 추가.
void AddKey(int Key)
{
    int Bucket = Hash(Key);
    for(int i = 0; i < KEY; i++)
    {
        if(HashTable[Bucket][i] == 0)
        {
            HashTable[Bucket][i] = Key;
            break;
        }
    }
}
 
// 데이터 검색.
bool FindKey(int Key)
{
    int Bucket = Hash(Key);
    for(int i = 0; i < KEY; i++)
    {
        if(HashTable[Bucket][i] == Key)
        {
            printf("데이터를 무사히 불러왔습니다.\n");
            printf("찾아온 데이터 : %d \n", HashTable[Bucket][i]);
            return true;
        }
    }
 
    printf("데이터가 존재하지 않습니다. \n");
    return false;
}




결과






'자료구조' 카테고리의 다른 글

덱(Deque)  (0) 2017.05.31
단방향 연결리스트 반대로 뒤집기.  (0) 2017.04.11
큐(Queue)  (0) 2017.01.07
스택(Stack)  (0) 2017.01.07
단방향 연결 리스트(Linked List)  (0) 2017.01.06

큐(Queue)


▷ 큐(Quene)





- 큐(Queue)의 데이터 제거는 대기 줄의 가장 앞에서 수행되며, 

  데이터의 삽입은 대기 줄의 가장 뒤에서 수행되는 제한된 리스트 구조를 말한다.


- 가장 먼저 삽입된 데이터가(First In) 가장 먼저 제거되는(First Out) 선입선출(FIFO)형태의 자료구조를 가지고 있다.


- 제일 처음에 입력된 데이터를 front라고 하고,


- 가장 나중에 입력된 데이터를 rear라고 한다.


- 데이터의 삽입은 rear에서 이루어지고,


- 삭제는 front에서 이루어진다.




제공되는 큐를 이용하여 만들기.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
#include <queue>
 
void main()
{
    queue <int> q;
 
    // 데이터 입력.
    for(int i = 0; i < 10; i++)
        q.push(i);
 
    // 데이터 출력.
    for(int i = 0; i < 10; i++)
    {
        printf("%d \n", q.front());
        q.pop();
    }
}




직접구현.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
using namespace std;
 
#define MAX        9
 
typedef struct QUEUE{
    int Data;
    struct QUEUE* pNext;
}QUEUE;
 
QUEUE* pHead = NULL;
QUEUE* pTail = NULL;
 
void push( int Data );
int front();
void pop();
 
void main()
{
    for(int i = 0; i < MAX; i++)
        push(i);
 
    for(int j = 0; j < MAX; j++)
    {
        printf("%d\n", front());
        pop();
    }
}
 
void push( int Data )
{
    QUEUE* NewNode = new QUEUE;
    NewNode->Data = Data;
    NewNode->pNext = NULL;
 
    if(pHead == NULL)
        pHead = NewNode;
    else
        pTail->pNext = NewNode;
    pTail = NewNode;
}
 
void pop()
{
    if( pHead == NULL )
    {
        printf("데이터가 존재하지 않습니다. \n");
        return;
    }
 
    QUEUE* pRemove = pHead;
    pHead = pHead->pNext;
    delete pRemove;
}
 
int front()
{
    if( pHead == NULL )
    {
        printf("데이터가 존재하지 않습니다. \n");
        return  -1;
    }
    return pHead->Data;
}



양방향




결과



'자료구조' 카테고리의 다른 글

단방향 연결리스트 반대로 뒤집기.  (0) 2017.04.11
해시 테이블 (Hash Table)  (0) 2017.01.08
스택(Stack)  (0) 2017.01.07
단방향 연결 리스트(Linked List)  (0) 2017.01.06
연결 리스트(Linked List)  (0) 2017.01.06

스택(Stack)


▷ 스택(Stack)


 - 스택은 데이터 입/출력이 한쪽으로만 접근할 수 있는 자료구조이다.


 - 가장 나중에 들어간 데이터가 제일 먼저나오게 되는 구조이다.


 - 선형구조 라고도 한다.



데이터의 입력이 A=> B=> C=> D 순서인 구조에서 자료를 꺼내거나 삭제하려면 다음과 같은 동작이 필요하다.




제공되는 스택을 쓸 경우.


push     : 데이터를 추가한다.


top       : 최상위 데이터를 반환한다.


pop      : 최상위 데이터를 삭제한다.


isEmpty : 현재 스택이 Null인지 아닌지 확인 후 true/false을 반환한다.




직접 구현할 경우 보통 사용법.


push     :  데이터를 추가한다.


Peek     :  최상위 데이터를 반환한다.


pop      :  최상위 데이터를 반환 후 데이터를 삭제 or 데이터를 삭제한다. ( 구현자 입맛대로. )


isEmpty : 현재 스택이 Null인지 아닌지 확인 후 true/false을 반환한다.




라이브러리 사용 스택.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
#include <stack>    // 스택을 사용하기 위한 include
 
void main()
{
    stack <int> s;    // 스택을 int형으로 사용하겠음.
 
    // 1부터 10까지 데이터를 추가.
    for(int i = 0; i < 10; i++)    
        s.push(i + 1);
 
    for(int i = 0; i < 10; i++)
    {
        printf("%d\n", s.top());
        s.pop();
    }
}
cs



직접 구현한 스택.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
using namespace std;
 
#define MAX        9
 
typedef struct STACK{
    int Data;
    struct STACK* pUnder;
}STACK;
 
STACK* pHead = NULL;
 
void push(int Data);
int peek();
void pop();
 
void main()
{
    for(int i = 0; i < MAX; i++)
        push(i);
 
    for(int i = 0; i < MAX; i++)
    {
        printf("%d\n", peek());
        pop();
    }
}
 
void push(int Data)
{
    STACK* NewNode = new STACK;
    NewNode->Data = Data;
    NewNode->pUnder = NULL;
 
    if(pHead != NULL)
        NewNode->pUnder = pHead;
    pHead = NewNode;
}
 
int peek()
{
    if(pHead == NULL)
    {
        printf("데이터가 존재하지 않습니다. \n");
        return -1;
    }
 
    return pHead->Data;
}
 
void pop()
{
    if(pHead == NULL)
    {
        printf("데이터가 존재하지 않습니다. \n");
        return;
    }
 
    STACK* pRemove = pHead;
    pHead = pHead->pUnder;
    delete pRemove;
}




결과




'자료구조' 카테고리의 다른 글

해시 테이블 (Hash Table)  (0) 2017.01.08
큐(Queue)  (0) 2017.01.07
단방향 연결 리스트(Linked List)  (0) 2017.01.06
연결 리스트(Linked List)  (0) 2017.01.06
퀵 정렬 (Quick sort)  (0) 2017.01.04
prev 1 ··· 22 23 24 25 26 27 28 29 next