728x90
반응형
집합이란?
집합 | 명확한 조건을 만족하는 자료의 모임 객관적으로 범위를 규정한 “어떤 것“의 모임 |
원소 | 집합 안에서 각각의 “어떤 것” |
집합의 특징
- 집합의 원소에는 순서가 없다.
- 집합에 포함되는 원소는 서로 달라야 한다.
- 집합은 집합을 원소로 가질 수 없다.
집합 ADT
- 유일한 개체들을 담는 용기
- 효율적인 구현을 위해 원소들의 정렬된 리스트로 표현한다.
직접응용 |
키워드 검색엔진
집합론에 관련된 다양한 계산
|
간접응용 |
알고리즘을 위한 보조 데이터 구조
다른 데이터구조를 구성하는 요소
|
연결리스트와 집합
- 같은 집합의 원소들은 하나의 연결 리스트로 관리
- 연결 리스트의 맨 앞의 원소를 집합의 대표 원소
하나의 원소로 이루어진 집합 | 연결 리스트로 된 두 집합 |
대표원소로 본인을 가리키고, 다음 노드를 가리키고 있지 않음 |
각 원소들은 대표 원소를 가리키고, 서로 연결됨 두 집합을 합치게 될 경우, 적은 수의 원소를 가진 집합을 다른 한 집합의 뒤에 합치는 것이 효율적 |
집합 구현: 배열
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//배열 A,B에 5개의 정수를 각각 입력후 합집합 계산
int main() {
int A[5], B[5];
int ans[10];
int i, j = 0, k = 5;
for (i = 0; i < 5; i++) scanf("%d", &A[i]);
for (i = 0; i < 5; i++) scanf("%d", &B[i]);
for (i = 0; i < 5; i++) ans[i] = A[i];
for (j = 0; j < 5; j++) {
for (i = 0; i < 5; i++) {
if (B[j] == A[i])
break;
if (i == 4) {
ans[k] = B[j];
k++;
}
}
}
for (i = 0; i < k; i++)printf("%d", ans[i]);
}
1. 두 개의 배열을 선언하고 값을 입력받는다.
2. 2중 반복문을 이용하여 두 배열 간의 값을 비교하고, 중복된 값이 없는 경우 결과 배열에 저장한다.
집합 구현: 연결리스트
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct ListNode {
int data;//현재 노드가 가지고 있는 데이터(값)
struct ListNode *next;//다음 노드의 위치
struct ListNode *pre;//이전 노드의 위치
}ListNode;
void add(ListNode *head, int rank, int value){//구조체 함수
ListNode* curr = head; //순회용 노드 생성
for(int i=0;i<rank;i++)curr= curr->next;
ListNode *p=(ListNode *)malloc(sizeof(ListNode));//추가할 노드를 동적할당한다.
p->data = value;
p->next = curr->next;
curr->next = p;
p->pre = curr;
(p->next)->pre = p;
// printf("추가된 노드의 데이터는 %c입니다.\n",p->data);
}
void function_arrangement(ListNode* head,ListNode* tail){
head->next = tail;
head->pre = NULL;
tail->next = NULL;
tail->pre = head;
}
int main(){
int num,cnt = 5;
ListNode* A_head = (ListNode*)malloc(sizeof(ListNode)); //헤드 노드 생성
ListNode* A_trail = (ListNode*)malloc(sizeof(ListNode)); //트레일 노드 생성
function_arrangement(A_head,A_trail);
ListNode* B_head = (ListNode*)malloc(sizeof(ListNode)); //헤드 노드 생성
ListNode* B_trail = (ListNode*)malloc(sizeof(ListNode)); //트레일 노드 생성
function_arrangement(B_head,B_trail);
ListNode* rst_head = (ListNode*)malloc(sizeof(ListNode)); //헤드 노드 생성
ListNode* rst_trail = (ListNode*)malloc(sizeof(ListNode)); //트레일 노드 생성
function_arrangement(rst_head,rst_trail);
for(int i=0;i<5;i++){scanf("%d",&num);add(A_head,i,num);}
for(int i=0;i<5;i++){scanf("%d",&num);add(B_head,i,num);}
ListNode* curr = A_head->next; //순회용 노드 생성
ListNode* result = rst_head->next; //합집합 저장 구조체 포인터 선언
for(int i=0;i<5;i++){
add(rst_head,i,curr->data);
// printf("%d\n", curr->data);
curr = curr->next;
}free(curr);
//합집합
ListNode* cmp_A = A_head->next; //순회용 노드 생성
ListNode* cmp_B = B_head->next; //순회용 노드 생성
for (int j=0;j<5;j++) {
cmp_A = A_head->next;
for (int i=0;i<5;i++) {
if(cmp_B->data == cmp_A->data)break;
if(i == 4){
// printf("check!\n");
add(rst_head,cnt,cmp_B->data);
cnt ++;
}
cmp_A = cmp_A->next;
}
cmp_B = cmp_B->next;
}
ListNode* prt = rst_head->next; //순회용 노드 생성
for(int i=0;i<cnt;i++){
printf("%d\n", prt->data);
prt = prt->next;
}free(prt);
}
1. 연결리스트 구조체를 정의한다.
2. 연결리스트의 데이터를 추가할 add함수를 생성한다. (C언어 알고리즘에서 상세히 다루겠다.)
3. 합집합은 두 집합의 공통된 원소의 집합이므로 순회를 통해 같은 값이 아닌 값을 결과 집합에 저장한다.
728x90
반응형
'Datastructure' 카테고리의 다른 글
[집합과 검색] #3. 검색과 복잡도 (0) | 2022.02.07 |
---|---|
[집합과 검색] #2. 검색 알고리즘 (0) | 2022.02.05 |
[연결리스트] #4. 연결리스트의 순회 (0) | 2022.01.16 |
[연결리스트] #3. 연결리스트의 삭제와 삽입 (2) | 2022.01.16 |
[연결리스트] #3. 연결리스트의 생성 (0) | 2022.01.16 |