일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- JavaScript
- MySQL
- Heap
- Spring
- Algorithm
- C
- 파이썬
- 백준
- mongoDB
- 자바
- JPA
- redis
- spring webflux
- Proxy
- react
- Galera Cluster
- IT
- MSA
- 알고리즘
- 자료구조
- 운영체제
- Data Structure
- 네트워크
- Java
- Kafka
- design pattern
- c언어
- 디자인 패턴
- OS
- 컴퓨터구조
Archives
- Today
- Total
시냅스
[자료구조] List - 원형 연결 리스트(Circular Linked List) 구현 본문
원형 연결 리스트
원형 연결 리스트는 일반적인 연결 리스트에 마지막 노드와 처음 노드를 연결시켜 원형으로 만든 구조이다.
단일 연결 리스트와 동일한 특징을 갖지만, 가장 첫 노드와 끝 노드가 연결된다는 특징을 갖는다.
원형 연결 리스트는 Cpu scheduling 에서 Ready queue나 스트림 버퍼를 구현하는 데에 많이 사용된다.
단, header는 tail과 동일하여 list의 0번째 node는 header의 다음 node가 된다.
특징
- 노드를 탐색하면서 순회에 용이하다.
- 반복적인 순회에서 끝을 확인해야할 필요가 없음.
- header 다음 node가 0번째 node가 된다.
- 이외에는 단일 연결리스트와 동일하다.
- 단일 연결 리스트
구현
- 리스트 생성
- 원소 추가
- 원소 반환
- 원소 제거
- 리스트 제거
리스트 생성
typedef struct CircularListNodeType
{
int data;
struct CircularListNodeType *pRLink;
} CircularListNode;
typedef struct CircularListType
{
int currentElementCount;
CircularListNode headerNode;
} CircularList;
구조체는 위와 같이 선언한다.
CircularList *createCircularList() // list 생성
{
CircularList *lst;
lst = calloc(1, sizeof(CircularList)); // list 초기화
return (lst);
}
list를 생성하여 반환한다.
원소 추가
int addCLElement(CircularList *pList, int position, CircularListNode element) // node 추가
{
CircularListNode *buf;
CircularListNode *new;
new = calloc(1, sizeof(CircularListNode));
new->data = element.data;
if (ZERO(pList->currentElementCount)) // node가 없는 경우
{
pList->headerNode.pRLink = new; // header 지정
new->pRLink = pList->headerNode.pRLink; // pRlink를 자기 자신으로 하여 순회할 수 있게 한다.
}
else // node가 있는 경우
{
buf = getCLElement(pList, position - 1); // 삽입할 포지션 전의 것을 지정한다.
new->pRLink = buf->pRLink; // node 간 연결
buf->pRLink = new;
if (position == pList->currentElementCount) // 만약 position이 맨 끝일 경우 header 로 지정한다.
pList->headerNode.pRLink = new;
}
pList->currentElementCount += 1; // node 개수를 늘려준다.
return (TRUE);
}
header 다음 node가 0번째 node이므로 유의해야 한다.
원소 반환
CircularListNode *getCLElement(CircularList *pList, int position) // node 반환
{
CircularListNode *head;
head = pList->headerNode.pRLink->pRLink; // header 는 tail이므로 0 index는 header의 다음이 된다.
while (position > 0) // position 만큼 이동한다.
{
head = head->pRLink;
position--;
}
return (head); // 원하는 node 반환
}
원하는 position을 탐색하여 반환한다.
원소 제거
int removeCLElement(CircularList *pList, int position) // 개별 node 삭제
{
CircularListNode *buf;
CircularListNode *delNode;
if (!(position)) // postion이 0 이라면
{
delNode = pList->headerNode.pRLink->pRLink; // 삭제할 node
buf = pList->headerNode.pRLink; // header
buf->pRLink = delNode->pRLink; // header의 다음을 delnode의 다음으로 지정한다.
}
else // position이 0이 아니라면
{
buf = getCLElement(pList, position - 1); // position 전의 node
delNode = getCLElement(pList, position); // position node
buf->pRLink = delNode->pRLink; // 이어준다.
}
free(delNode);
delNode = NULL;
pList->currentElementCount--;
return (TRUE);
}
마찬가지로 header의 다음이 0번째 node라는 것에 유의해야 한다.
리스트 제거
void clearCircularList(CircularList *pList) // 내부 node 전체 삭제
{
CircularListNode *head;
CircularListNode *next;
int idx;
head = pList->headerNode.pRLink->pRLink; // 0번째 node는 header 다음이다.
while (idx < pList->currentElementCount) // 개수만큼 삭제한다.
{
next = head->pRLink;
head->pRLink = NULL;
free(head);
head = next;
idx++;
}
head = NULL;
next = NULL;
pList->currentElementCount = 0;
}
void deleteCircularList(CircularList *pList) // node와 list를 삭제한다.
{
clearCircularList(pList);
free(pList);
pList = NULL;
}
순환에 있어서도 0번째 다음을 시작 node로 지정해야 한다.
'자료구조' 카테고리의 다른 글
[자료구조] 연결리스트를 활용한 다항식 계산 구현 (0) | 2022.04.23 |
---|---|
[자료구조] List - 이중연결 리스트(Doubly Linked List) 구현 (0) | 2022.04.21 |
[자료구조] List - 단일 연결 리스트(Singly Linked List) 구현 (0) | 2022.04.17 |
[자료구조] List - 배열 리스트(Array List) 구현 (0) | 2022.04.17 |
TIL : Graph 자료구조 (0) | 2021.09.27 |
Comments