연결 리스트 - 순환 연결 리스트

2025. 4. 13. 14:14·자료구조

교재 - 파이썬으로 배우는 자료구조(저자 유석종)

 


1. 순환 연결 리스트

`체인` : 연결 리스트의 마지막 노드의 링크에 None 값이 저장되어 있는 경우

`순환 연결 리스트` : 마지막 노드의 링크가 None이 아니고 그 리스트의 첫 노드에 다시 연결되어 있는 경우

순환 연결 리스트는 리스트 변수를 변경해도 여전히 전체 리스트가 연결 상태를 유지하는 특징이 있음.

 

 


2. 순환 연결 리스트의 길이

순환 연결 리스트는 링크가 None인 마지막 노드가 없기 때문에 시작 노드로 다시 되돌아 오는 순간이 전체 리스트를 모두 탐색한 시점임.

 

length_list 함수는 빈 리스트 여부를 검사.

빈 리스트가 아닌 경우는 첫 노드에서부터 temp를 이동시키면서 head 노드의 위치로 되돌아올 때까지 count 변수를 증가시킴.

 

# 5.7. 순환 연결 리스트의 길이
print("\n5.7. 순환 연결 리스트의 길이")
class Node:
    def __init__(self, item):
        self.data = item
        self.link = None

class CircularList:
    def __init__(self):
        self.head = self.tail = None

    def attach(self, item):     # 리스트 뒤에 노드 추가
        node = Node(item)
        if not self.head:
            self.head = node
            self.tail = node
        elif self.tail:
            self.tail.link = node
            self.tail = node
        node.link = self.head

    def length_list(self):      # 리스트 길이 세기
        if not self.head: return 0
        count = 0
        temp = self.head
        while True:
            count += 1
            temp = temp.link
            if temp == self.head: break
        return count

    def view(self):
        temp = self.head
        print("[", end=' ')
        while temp:
            print(temp.data, end=' ')
            temp = temp.link
            if temp is self.head: break
        print("]", end=' ')
        if self.head:
            print("  H=%d T=%d" % (self.head.data, self.tail.data))
        else: print("빈 리스트")

lst = CircularList()
for item in [200, 100, 150, 200, 300, 250]:
    lst.attach(item)
lst.view()
print("리스트 길이 =", lst.length_list())
# 출력 결과
5.7. 순환 연결 리스트의 길이
[ 200 100 150 200 300 250 ]   H=200 T=250
리스트 길이 = 6

 

 

 

 


3. 역순 연결 리스트

`역순 연결 리스트` : 리스트의 노드들을 반대 방향으로 연결한 리스트.

예를 들어 head -> 100 -> 200 -> 300 이라면

역순 연결리스트는 head -> 300 -> 200 -> 100

 

[ 알고리즘 | 역순 연결 리스트 ]

1. 빈 리스트이거나 노드가 1개인 경우 : head 변수를 반환하고 종료한다.

2. 리스트 노드가 2개 이상인 경우

    (1) third 변수가 second 노드를 가리키게 된다.

    (2) second 변수가 first 노드를 참조하게 된다.

    (3) first 변수를 다음 노드로 이동시킨다.

    (4) second 노드의 링크에 third 값을 저장한다.

    (5) first 가 Nonde 이 아닐 때까지 2-(1)번부터 반복한다.

 

이 알고리즘의 시간 복잡도는 리스트의 길이(O(N))에 비례함.

 

아래 프로그램 5.8.의 reverse 함수에 역순 리스트 알고리즘이 구현되어 있음. 실행 결과를 보면 리스트의 연결 순서가 반대로 되어 있는 것을 확인할 수 있음.

# 5.8. 역순 연결 리스트
print("\n5.8. 역순 연결 리스트")
class Node:
    def __init__(self, item):
        self.data = item
        self.link = None

class SinglyLinkedlist:
    def __init__(self):
        self.head = self.tail = None

    def view(self):
        temp = self.head
        print("[", end=' ')
        while temp:
            print(temp.data, end=' ')
            temp = temp.link
        print("]", end=' ')
        if self.head:
            print("  H=%d T=%d" % (self.head.data, self.tail.data))
        else: print("빈 리스트")

    def attach(self, item):
        node = Node(item)
        if not self.head:
            self.head = node
            self.tail = node
        elif self.tail:
            self.tail.link = node
            self.tail = node

    def reverse(self):
        first = self.head
        second = third = None
        self.tail = self.head
        while first:
            third = second
            second = first
            first = first.link
            second.link = third
        self.head = second

lst1 = SinglyLinkedlist()
for item in [200, 100, 150, 200, 300, 250]:
    lst1.attach(item)

lst1.view()
lst1.reverse()
lst1.view()
# 실행 결과
5.8. 역순 연결 리스트
[ 200 100 150 200 300 250 ]   H=200 T=250
[ 250 300 200 150 100 200 ]   H=250 T=200

 

 

헷갈렸던 점

reverser() 의 마지막 코드 self.head = second 부분.

: 역순 리스트 알고리즘을 통해 second가 현재까지 뒤집힌 리스트의 맨 앞이 됨.

원래 : head → [200] → [100] → [150] → ... → [250] → None
뒤집고 나면 : head → [250] → [300] → ... → [200] → None

 

루프 끝나면

[250] → [300] → ... → [200]

이런 상태. 

 

루프 시작할 때

first = self.head
self.tail = self.head

이랬으므로 self.head는 여전히 [200]을 가리키는 중. 그래서 역순으로 잘 뒤집어도 head는 여전히 처음 노드니까 self.head = second를 통해 head를 새로 바뀐 리스트의 첫번째 노드로 바꿔줌.

 

 

 


 

'자료구조' 카테고리의 다른 글
  • 자료구조 스터디 1주차 ~ 4주차
  • 연결리스트 - 이중 연결 리스트
  • 연결 리스트 - 연결 리스트 연산
  • 연결 리스트 - 단일 연결 리스트
seo_young
seo_young
  • seo_young
    86400개의 발자국
    seo_young
  • 전체
    오늘
    어제
    • 분류 전체보기 (56)
      • 리눅스 (11)
      • 웹 기초 (9)
      • 회로이론1 (1)
      • 자료구조 (15)
      • 백준 - C (10)
      • 백준 - 파이썬 (7)
      • 크롤링 스터디 (0)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
seo_young
연결 리스트 - 순환 연결 리스트
상단으로

티스토리툴바