728x90
728x90
원형 연결 리스트(Circular Linked List)
원형 연결 리스트의 개념
- 단순 연결 리스트(Singly Linked List)
- 끝까지 방문한 후에는 더 이상 방문할 곳이 없어 종료되므로 다시 방문하려면 헤드(head)부터 재시작해야 한다.
- 원형 연결 리스트(Circular Linked List)는 단순 연결 리스트의 마지막 노드가 다시 첫 번째 노드를 가리키도록 설정되어 리스트 형태가 원(Circle) 형태로 구성된다.
- 시작 위치와 다음 위치가 계속 이어진 후, 마지막에 다시 시작 위치로 돌아오는 형태
- 원형 연결리스트는 단순 연결 리스트와 마찬가지로 데이터 삽입에서 오버헤드가 발생하지 않는다.
원형 연결 리스트의 원리
- 원형 연결 리스트의 원리 및 구조도 단순 연결 리스트와 많은 부분이 비슷하다.
노드 구조
- 단순 연결 리스트와 마찬가지로 원형 연결 리스트를 구현하기 위해서는 노드(Node)를 사용해야 한다.

- 원형 연결 리스트도 단순 연결 리스트와 마찬가지로 첫 번째 노드를 가리키는 헤드(head)를 사용한다.
- 헤드는 원형 연결 리스트의 시작점으로 사용한다.

노드(데이터) 삽입
- 1단계 : 삽입할 노드를 생성한다.
- 2단계 : 순서에 맞게 링크를 수정한다.
- 새 노드의 링크에 이전 노드의 링크를 복사한다.
- 이전 노드의 링크에 새 노드를 지정한다.

- 원형 연결 리스트에서 중간 노드를 삽입하는 과정은 단순 연결 리스트의 과정과 방식이 동일하다.
- 하지만, 첫 번째 노드 삽입이나 마지막 노드 삽입 등은 다르게 처리된다.
노드(데이터) 삭제
- 1단계 : 삭제할 노드의 바로 앞 노드 링크를 수정한다.
- 삭제할 노드의 링크를 바로 앞 노드의 링크로 복사하여 앞 노드가 삭제할 노드의 다음 노드를 가리키게 한다.
- 2단계 : 삭제할 노드를 삭제한다.

- 원형 연결 리스트에서 중간 노드를 삭제하는 과정은 단순 연결 리스트의 과정과 방식이 동일하다.
- 하지만, 첫 번째 노드 삭제나 마지막 노드 삭제 등은 다르게 처리된다.
원형 연결 리스트의 구현

- 헤드(head) : 첫 번째 노드를 가리킨다.
- 현재(current) : 지금 처리 중인 노드를 가리킨다.
- 이전(pre) : 현재 처리 중인 노드의 바로 앞 노드를 가리킨다.
- 처음에는 모두 비어 있으므면 되므로 다음과 같이 초기화한다.
memory = [] head, current, pre = None, None, None
① 원형 연결 리스트 생성
노드 생성
- 노드는 클래스(Class)를 사용하여 구현한다.
class Node() : def __init__(self): # 생성자 함수 : 데이터형을 생성할 때 자동으로 실행 self.data = None self.Link = None
- 노드 생성 및 확인
node1 = Node() node1.data = "Apple" print(node1.data, end = ' ') node1.link = node1 # 첫 번째 노드와 마지막 노드가 연결되도록 설정한다.
노드 연결
- 첫 번째 노드의 링크에 두 번째 노드 이름(node2)을 넣어 준다.
- 그리고 두 번째 노드의 링크에 첫 번째 노드를 연결해서 원형 구조를 갖게 해준다.
node2 = Node() node2.data = "Banana" node1.link = node2 node2.link = node1
노드 초기화
첫 번째 데이터
- 첫 번째 노드이므로 헤드는 첫 번째 노드를 가리키도록 하고, 새 노드의 링크는 헤드가 가리키는 노드로 연결한다.
- 첫 번째 노드이므로 결국 자신이 자신을 가리키는 형태가 된다.
node = Node() node.data = dataArray[0] # 첫 번째 노드 head = node node.link = head memory.append(node)
두 번째 이후 데이터
- 새 노드를 기준 노드의 링크에 저장하기 전에 기존 노드를 잠시 저장한 후 생성해야 한다.
- 그리고 새 노드의 링크에 헤드가 가리키는 노드를 연결함으로써 원형 연결 리스트의 구조를 유지해야 한다.
pre = node node = Node() node.data = data # 두 번째 이후 노드 pre.link = node node.link = head memory.append(node)
② 노드 삽입
- 노드를 원형 연결 리스트의 맨 앞, 중간, 마지막에 삽입하는 경우로 나누어 생각해 볼 수 있다.
첫 번째 노드 삽입
node = Node() node.data = "item" node.link = head last = head # 마지막 노드를 첫 번째 노드로 우선 지정 while 마지막 노드까지 : # 마지막 노드를 찾으면 반복 종료 last = last.link # last를 다음 노드로 변경 last.link = node # 마지막 노드의 링크에 새 노드 지정 head = node
중간 노드 삽입
current = head while 마지막 노드까지 : pre = current current = current.link if current.data == origin_data : node = Node() node.data = new_data node.link = current pre.link = node
마지막 노드 삽입
# 마지막 노드까지 new_data 를 찾지 못한 후 node = Node() node.data = new_data current.link = node node.link = head
함수 완성
def insertNode(findData, insertData) : global memory, head, current, pre if head.data == findData : # 첫 번째 노드 삽입 node = Node() node.data = insertData node.link = head last = head # 마지막 노드를 첫 번째 노드로 우선 지정 while last.link != head: # 마지막 노드를 찾으면 반복 종료 last = last.link # last를 다음 노드로 지정 last.link = node # 마지막 노드의 링크에 새 노드 지정 head = node return current = head while current.link != head: # 중간 노드 삽입 pre = current current = current.link if current.data == findData: node = Node() node.data = insertData node.link = current return node = Node() # 마지막 노드 삽입 node.data = insertData current.link = node node.link = head
③ 노드 삭제
첫 번째 노드 삭제
current = head head = head.link last = head while last.link != current : # 마지막 노드를 찾으면 반복 종료 last = last.link # last를 다음 노드로 변경 last.link = head # 마지막 노드의 링크에 head가 기리키는 노드 지정 del(current)
첫 번째 외 노드 삭제
current = head while current.link != head : pre = current current = current.link if current.data == finding_data : pre.link = current.link del(current)
함수 완성
def deleteNode(deleteData) : global memory, head, current, pre if head.data == deleteData : # 첫 번째 노드 삭제 current = head head = head.link last = head while last.link != current : # 마지막 노드를 찾으면 반복 종료 last = last.link # last를 다음 노드로 변경 last.link = head # 마지막 노드의 링크에 head가 가리키는 노드 지정 del(current) return current = head # 첫 번째 외 노드 삭제 while current.link != head : pre = current current = current.link if current.data == deleteData : # 중간 노드를 찾았을 때 pre.link = current.link del(current) return
④ 노드 검색
- 검색할 데이터의 노드를 반환하는 방식으로 구현해본다.
함수 완성
def findNode(findData) : global memory, head, current, pre current = head if current.data == findData : return current while current.link != head : current = current.link if current.data == findData : return current return Node() # 빈 노드 반환
원형 연결 리스트의 완성
# 원형 연결 리스트의 구현 ## 클래스와 함수 선언 부분 ## class Node() : def __init__(self) : self.data = None self.link = None def printNodes(start) : current = start if current.link == None: return print(current.data, end = ' ') while current.link != start : current = current.link print(current.data, end = ' ') print() def insertNode(findData, insertData) : global memory, head, current, pre if head.data == findData : # 첫 번째 노드 삽입 node = Node() node.data = insertData node.link = head last = head # 마지막 노드를 첫 번째 노드로 우선 지정 while last.link != head: # 마지막 노드를 찾으면 반복 종료 last = last.link # last를 다음 노드로 지정 last.link = node # 마지막 노드의 링크에 새 노드 지정 head = node return current = head while current.link != head: # 중간 노드 삽입 pre = current current = current.link if current.data == findData: node = Node() node.data = insertData node.link = current return node = Node() # 마지막 노드 삽입 node.data = insertData current.link = node node.link = head def deleteNode(deleteData) : global memory, head, current, pre if head.data == deleteData : # 첫 번째 노드 삭제 current = head head = head.link last = head while last.link != current : # 마지막 노드를 찾으면 반복 종료 last = last.link # last를 다음 노드로 변경 last.link = head # 마지막 노드의 링크에 head가 가리키는 노드 지정 del(current) return current = head # 첫 번째 외 노드 삭제 while current.link != head : pre = current current = current.link if current.data == deleteData : # 중간 노드를 찾았을 때 pre.link = current.link del(current) return def findNode(findData) : global memory, head, current, pre current = head if current.data == findData : return current while current.link != head : current = current.link if current.data == findData : return current return Node() # 빈 노드 반환 ## 전역 변수 선언 부분 ## memory = [] head, current, pre = None, None, None dataArray = ["다현", "정연", "쯔위", "사나", "지효"] ## 메인 코드 부분 ## if __name__ == "__main__": node = Node() node.data = dataArray[0] # 첫 번째 노드 head = node node.link = head memory.append(node) for data in dataArray[1:] : # 두 번째 이후 노드 pre = node node = Node() node.data = data pre.link = node node.link = head memory.append(node) printNodes(head) # 삽입 예 insertNode("다현", "화사") printNodes(head) insertNode("사나", "솔라") printNodes(head) insertNode("지민", "문별") printNodes(head) # 삭제 예 deleteNode("다현") printNodes(head) deleteNode("쯔위") printNodes(head) deleteNode("지효") printNodes(head) deleteNode("지민") printNodes(head) # 검색 예 fNode = findNode("다현") print(fNode.data) fNode = findNode("쯔위") print(fNode.data) fNode = findNode("지민") print(fNode.data)
결과 보기
다현 정연 쯔위 사나 지효 화사 다현 정연 쯔위 사나 지효 화사 다현 정연 쯔위 사나 지효 화사 다현 정연 쯔위 사나 지효 문별 화사 정연 쯔위 사나 지효 문별 화사 정연 사나 지효 문별 화사 정연 사나 문별 화사 정연 사나 문별 None None None
728x90
728x90
'Computer Science > 자료구조' 카테고리의 다른 글
[C] 원형 연결 리스트(Circular Linked List) (0) | 2022.07.12 |
---|---|
[C] 단순 연결 리스트(Singly Linked List) (0) | 2022.07.12 |
[Python] 큐(Queue) (0) | 2022.07.01 |
[Python] 스택(Stack) (0) | 2022.07.01 |
[Python] 이진 탐색(Binary Search) (0) | 2022.06.29 |
[Python] 순차 탐색(Sequential Search) (0) | 2022.06.29 |
[Python] 단순 연결 리스트(Singly Linked List) (0) | 2022.06.22 |
[Python] 선형 연결 리스트(Linear Linked List) (0) | 2022.06.22 |