Chapter 05
원형 연결 리스트
Circular Linked List
Part 1  원형 연결 리스트의 개념 · Concept of Circular Linked List
Part 2  원형 연결 리스트의 구현 · Implementation of Circular Linked List
Part 3  원형 연결 리스트의 응용 · Applications of Circular Linked List
01
Part 1
원형 연결 리스트의 개념
Concept of Circular Linked List
원형 연결 리스트의 기본 구조와 삽입/삭제 원리를 학습합니다

생활 속 원형 연결 리스트 Circular Lists in Everyday Life

한국어
일상에서의 원형 구조

우리 주변에는 끝이 없이 반복되는 구조가 많습니다.

  • 회전목마 - 마지막 말 다음에 다시 첫 번째 말
  • 트랙 경기 - 결승선을 지나면 다시 출발점
  • 시계 - 12시 다음은 다시 1시
  • 요일 - 일요일 다음은 다시 월요일
월 Mon 화 Tue 수 Wed 목 Thu 금 Fri 토 Sat 일 Sun 끝없이 순환 Endless cycle
이러한 순환(Circular) 구조를 프로그래밍으로 표현한 것이 바로 원형 연결 리스트입니다.
English
Circular Structures Around Us

Many structures in daily life repeat endlessly.

  • Carousel - after the last horse comes the first again
  • Track race - crossing the finish line returns to start
  • Clock - after 12 o'clock comes 1 again
  • Days of week - after Sunday comes Monday again
Mon Tue Wed Thu Fri Sat Sun Endless Cycle
This circular structure, expressed in programming, is the circular linked list.

원형 연결 리스트의 개념 Concept of Circular Linked List

한국어
원형 연결 리스트(Circular Linked List)란 마지막 노드의 link가 None이 아니라 첫 번째 노드를 가리키는 연결 리스트입니다.
핵심 특징
  • 마지막 노드의 link → 첫 번째 노드
  • None으로 끝나지 않음
  • 어느 노드에서든 모든 노드를 순회 가능
  • 순회 시 시작 노드로 돌아오면 종료
head 다현 정연 쯔위 마지막 노드가 첫 노드를 가리킴
순회 시 종료 조건을 정확히 지정하지 않으면 무한 루프에 빠질 수 있습니다!
English
A Circular Linked List is a linked list where the last node's link points to the first node instead of None.
Key Characteristics
  • Last node's link → first node
  • Does not end with None
  • Every node can reach all other nodes
  • Traversal ends when returning to start node
head 다현 정연 쯔위 Last node points to first node
Without a precise termination condition, traversal can fall into an infinite loop!

단순 vs 원형 연결 리스트 비교 Simple vs Circular Linked List

한국어
단순 연결 리스트
  • 마지막 노드의 link = None
  • 한 방향으로만 순회
  • 끝에 도달하면 종료
  • while current != None
원형 연결 리스트
  • 마지막 노드의 link = 첫 노드
  • 순환하며 순회
  • 시작점으로 돌아오면 종료
  • while current.link != head
구분단순 연결 리스트원형 연결 리스트
마지막 linkNone첫 번째 노드
순회 종료None 만남시작 노드 재방문
활용일반 목록순환 스케줄링
Simple Linked List A B C None Circular Linked List A B C Last links back to first No end (None) → continuous loop through all nodes
English
Simple Linked List
  • Last node's link = None
  • Traversal in one direction only
  • Stops when reaching the end
  • while current != None
Circular Linked List
  • Last node's link = first node
  • Cyclic traversal
  • Stops when returning to start
  • while current.link != head
CategorySimple Linked ListCircular Linked List
Last linkNoneFirst node
Traversal endReaching NoneRevisiting start node
Use caseGeneral listsCyclic scheduling
Simple Linked List A B C None Circular Linked List A B C Last links back to first No end (None) → continuous loop through all nodes

노드 구조 Node Structure

한국어
노드 클래스 정의

원형 연결 리스트의 노드 구조는 단순 연결 리스트와 동일합니다.

class Node() :
    def __init__(self) :
        self.data = None   # 데이터 필드
        self.link = None   # 링크 필드
Node data "다현" link next node Same structure, different target Simple: link = None Circular: link = head
노드의 구조는 같지만, link가 가리키는 대상이 다릅니다.
- 단순: 마지막 노드의 link → None
- 원형: 마지막 노드의 link → 첫 번째 노드
English
Node Class Definition

The node structure for a circular linked list is identical to a simple linked list.

class Node() :
    def __init__(self) :
        self.data = None   # data field
        self.link = None   # link field
Node data "다현" link next node Same structure, different target Simple: link = None Circular: link = head
The node structure is the same, but the target of link differs.
- Simple: last node's link → None
- Circular: last node's link → first node

노드 삽입 원리 (중간) Insertion Principle (Middle)

한국어
정연과 쯔위 사이에 "재남" 삽입
1
새 노드 newNode를 생성하고 데이터에 "재남"을 저장합니다.
2
newNode.link에 정연 노드의 link(쯔위)를 대입합니다.
newNode.link = node2.link
3
정연 노드의 link를 newNode로 변경합니다.
node2.link = newNode
Before: 정연 쯔위 ... After: 정연 재남 new! 쯔위 ... Step 2: newNode.link = node2.link (재남 points to 쯔위 first) Step 3: node2.link = newNode (정연 now points to 재남) Order matters! Step 2 MUST come before Step 3
순서가 중요합니다! Step 2와 3의 순서가 바뀌면 쯔위 노드를 잃어버립니다.
English
Insert "재남" between 정연 and 쯔위
1
Create a new node newNode and store "재남" in its data.
2
Assign 정연's link (쯔위) to newNode.link.
newNode.link = node2.link
3
Change 정연's link to newNode.
node2.link = newNode
Before: 정연 쯔위 ... After: 정연 재남 new! 쯔위 ... Step 2: newNode.link = node2.link (재남 points to 쯔위 first) Step 3: node2.link = newNode (정연 now points to 재남) Order matters! Step 2 MUST come before Step 3
Order matters! If Step 2 and 3 are swapped, the 쯔위 node will be lost.

노드 삭제 원리 (중간) Deletion Principle (Middle)

한국어
"쯔위" 노드 삭제 (정연과 사나 사이)
1
삭제할 노드(쯔위)의 이전 노드(정연)의 link를 삭제할 노드의 다음 노드(사나)로 변경합니다.
node2.link = node3.link
2
삭제할 노드(쯔위)를 메모리에서 제거합니다.
del(node3)
Before: 정연 쯔위 delete 사나 After: 정연 사나 Step 1: node2.link = node3.link Step 2: del(node3) 쯔위 is removed; 정연 now links directly to 사나
삭제는 삽입보다 간단합니다. 이전 노드의 link만 변경하면 됩니다.
English
Delete "쯔위" node (between 정연 and 사나)
1
Change the previous node's (정연) link to point to the node after the one being deleted (사나).
node2.link = node3.link
2
Remove the deleted node (쯔위) from memory.
del(node3)
Before: 정연 쯔위 delete 사나 After: 정연 사나 Step 1: node2.link = node3.link Step 2: del(node3) 쯔위 is removed; 정연 now links directly to 사나
Deletion is simpler than insertion. You only need to change the previous node's link.

Code05-01: 원형 연결 리스트 생성 Creating a Circular Linked List

한국어
class Node() :
    def __init__(self) :
        self.data = None
        self.link = None

node1 = Node()
node1.data = "다현"
node1.link = node1  # 자기 자신을 가리킴

node2 = Node()
node2.data = "정연"
node1.link = node2
node2.link = node1  # 다시 node1을 가리킴

node3 = Node()
node3.data = "쯔위"
node2.link = node3
node3.link = node1  # 다시 node1을 가리킴

node4 = Node()
node4.data = "사나"
node3.link = node4
node4.link = node1

node5 = Node()
node5.data = "지효"
node4.link = node5
node5.link = node1  # 마지막 → 첫 번째

# 순회 출력
current = node1
print(current.data, end=" ")
while current.link != node1 :
    current = current.link
    print(current.data, end=" ")
출력: 다현 정연 쯔위 사나 지효
head 다현 정연 쯔위 사나 지효 node5.link = node1 다현 정연 쯔위 사나 지효
English
How It Works
  • Each new node is added, and its link initially points back to node1
  • The previous last node's link is updated to point to the new node
  • Traversal: print first, then loop while current.link != node1
class Node() :
    def __init__(self) :
        self.data = None
        self.link = None

node1 = Node()
node1.data = "다현"
node1.link = node1  # points to itself

node2 = Node()
node2.data = "정연"
node1.link = node2
node2.link = node1  # points back to node1

node3 = Node()
node3.data = "쯔위"
node2.link = node3
node3.link = node1  # points back to node1

node4 = Node()
node4.data = "사나"
node3.link = node4
node4.link = node1

node5 = Node()
node5.data = "지효"
node4.link = node5
node5.link = node1  # last → first

# traversal output
current = node1
print(current.data, end=" ")
while current.link != node1 :
    current = current.link
    print(current.data, end=" ")
Output: 다현 정연 쯔위 사나 지효
head 다현 정연 쯔위 사나 지효 node5.link = node1 다현 정연 쯔위 사나 지효

Code05-02: 중간 삽입 구현 Middle Insertion Implementation

한국어
정연과 쯔위 사이에 "재남" 삽입
# 앞의 Code05-01 이후에 추가

newNode = Node()
newNode.data = "재남"

# Step 1: 새 노드의 link를 정연의 다음(쯔위)으로
newNode.link = node2.link

# Step 2: 정연의 link를 새 노드로 변경
node2.link = newNode

# 순회 출력
current = node1
print(current.data, end=" ")
while current.link != node1 :
    current = current.link
    print(current.data, end=" ")
출력: 다현 정연 재남 쯔위 사나 지효
After insertion (6 nodes): head 다현 정연 재남 쯔위 사나 지효 다현 정연 재남 쯔위 사나 지효
English
Insert "재남" between 정연 and 쯔위

Two pointer updates are needed:

  1. newNode.link = node2.link - new node points to 쯔위
  2. node2.link = newNode - 정연 points to new node
# after Code05-01, add:

newNode = Node()
newNode.data = "재남"

# Step 1: new node's link to 정연's next (쯔위)
newNode.link = node2.link

# Step 2: change 정연's link to new node
node2.link = newNode

# traversal output
current = node1
print(current.data, end=" ")
while current.link != node1 :
    current = current.link
    print(current.data, end=" ")
Output: 다현 정연 재남 쯔위 사나 지효
After insertion (6 nodes): head 다현 정연 재남 쯔위 사나 지효 다현 정연 재남 쯔위 사나 지효

Code05-03: 중간 삭제 구현 Middle Deletion Implementation

한국어
"쯔위" 노드 삭제

정연(또는 재남 삽입 후라면 재남)과 사나 사이에서 쯔위를 제거합니다.

# 쯔위(node3) 삭제

# Step 1: 이전 노드의 link를 삭제 노드의 다음으로
node2.link = node3.link

# Step 2: 노드 메모리 해제
del(node3)

# 순회 출력
current = node1
print(current.data, end=" ")
while current.link != node1 :
    current = current.link
    print(current.data, end=" ")
출력: 다현 정연 사나 지효
After deletion (4 nodes): head 다현 정연 쯔위 사나 지효 다현 정연 사나 지효
Python에서 del은 변수 참조를 삭제합니다. 가비지 컬렉터가 실제 메모리를 회수합니다.
English
Delete "쯔위" Node

Remove 쯔위 from the list by bypassing it.

  1. node2.link = node3.link - 정연 skips over 쯔위 to 사나
  2. del(node3) - free the deleted node
# delete 쯔위 (node3)

# Step 1: previous node's link to deleted node's next
node2.link = node3.link

# Step 2: free node memory
del(node3)

# traversal output
current = node1
print(current.data, end=" ")
while current.link != node1 :
    current = current.link
    print(current.data, end=" ")
Output: 다현 정연 사나 지효
After deletion (4 nodes): head 다현 정연 쯔위 사나 지효 다현 정연 사나 지효
In Python, del removes the variable reference. The garbage collector reclaims the actual memory.

Part 1 연습문제 Practice Problems

한국어
연습문제 1

원형 연결 리스트에서 마지막 노드의 link가 가리키는 것은 무엇인가?

  1. None
  2. 자기 자신
  3. 첫 번째 노드
  4. 이전 노드
연습문제 2

원형 연결 리스트에서 순회 시 종료 조건으로 적절한 것은?

  1. current == None
  2. current.link == None
  3. current.link == head
  4. current.data == None
연습문제 3

노드 A → B → C (원형)에서 B 뒤에 D를 삽입할 때, 올바른 순서는?

  1. B.link = DD.link = C
  2. D.link = CB.link = D
  3. D.link = BC.link = D
  4. C.link = DD.link = B
정답: 1-c, 2-c, 3-b
English
Problem 1

In a circular linked list, what does the last node's link point to?

  1. None
  2. Itself
  3. The first node
  4. The previous node
Problem 2

What is the correct traversal termination condition for a circular linked list?

  1. current == None
  2. current.link == None
  3. current.link == head
  4. current.data == None
Problem 3

To insert D after B in A → B → C (circular), the correct order is:

  1. B.link = D then D.link = C
  2. D.link = C then B.link = D
  3. D.link = B then C.link = D
  4. C.link = D then D.link = B
Answers: 1-c, 2-c, 3-b
02
Part 2
원형 연결 리스트의 구현
Implementation of Circular Linked List
일반 형태의 삽입, 삭제, 검색 함수를 구현합니다

일반 형태의 변수 General Form Variables

한국어
핵심 변수 3가지
1
head : 첫 번째 노드를 가리키는 포인터. 리스트 전체의 시작점 역할을 한다.
2
current : 현재 처리 중인 노드를 가리키는 포인터. 순회 시 이동하며 사용된다.
3
pre : current 바로 이전 노드를 가리키는 포인터. 삽입/삭제 시 연결 조정에 필요하다.
데이터 준비
# 메모리 리스트와 데이터 배열 memory = [] head, current, pre = None, None, None dataArray = ["다현", "정연", "쯔위", "사나", "지효"]
head 다현 pre 정연 current 쯔위 사나 circular link back to head
English
Three Key Variables
1
head: Points to the first node. Serves as the entry point of the entire list.
2
current: Points to the node currently being processed. Moves during traversal.
3
pre: Points to the node just before current. Needed for link adjustment during insert/delete.
Data Preparation
# Memory list and data array memory = [] head, current, pre = None, None, None dataArray = ["다현", "정연", "쯔위", "사나", "지효"]
head 다현 pre 정연 current 쯔위 사나 circular link back to head

printNodes 함수와 리스트 생성 printNodes & List Creation

한국어
printNodes 함수

원형 연결 리스트의 출력은 일반 연결 리스트와 다르다. 종료 조건이 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()
핵심 포인트: current.link != start 조건으로 한 바퀴를 돌았는지 확인한다. 일반 연결 리스트의 current != None과 비교하자.
리스트 생성 로직
1
첫 번째 노드: 노드를 생성하고 데이터를 설정한 후, 자기 자신을 가리키게 한다 (node.link = head). 이것이 초기 원형을 형성한다.
2
이후 노드: 이전 노드를 pre에 저장하고, 새 노드를 생성하여, pre에서 새 노드로 연결하고, 새 노드에서 다시 head로 연결한다.
Step 1: First node (self-link) 다현 self-link Step 2: Add second node 다현 정연 back to head head
English
printNodes Function

Printing a circular linked list differs from a regular linked list. The termination condition is not None but rather checking whether we have returned to the start node.

def printNodes(start): current = start if current.link == None: return print(current.data, end=' ') while current.link != start: # Key! current = current.link print(current.data, end=' ') print()
Key Point: The condition current.link != start checks if we have gone around once. Compare with current != None in a regular linked list.
List Creation Logic
1
First node: Create node, set data, then make it point to itself (node.link = head). This forms the initial circle.
2
Subsequent nodes: Save previous node in pre, create new node, link pre to new node, then link new node back to head.
Step 1: First node (self-link) 다현 self-link Step 2: Add second node 다현 정연 back to head head

Code05-04 전체 코드 Complete Code

한국어
Code05-04: 원형 연결 리스트 생성
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() memory = [] head, current, pre = None, None, None dataArray = ["다현", "정연", "쯔위", "사나", "지효"]
실행 결과:
다현 정연 쯔위 사나 지효
head 다현 정연 쯔위 사나 지효
English
Code05-04: Circular Linked List Creation
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() memory = [] head, current, pre = None, None, None dataArray = ["다현", "정연", "쯔위", "사나", "지효"]
Main Block
if __name__ == "__main__": node = Node() node.data = dataArray[0] head = node node.link = head # self-link memory.append(node) for data in dataArray[1:]: pre = node node = Node() node.data = data pre.link = node # prev->new node.link = head # new->head memory.append(node) printNodes(head)
Output:
다현 정연 쯔위 사나 지효
head 다현 정연 쯔위 사나 지효

노드 삽입 - 첫 번째 노드 Insert at Head (Code05-05)

한국어
첫 번째 노드 앞에 삽입하는 과정
1
새 노드를 생성하고 데이터를 설정한다.
2
새 노드의 link를 현재 head로 설정한다.
3
마지막 노드를 찾는다 (link가 head인 노드).
4
마지막 노드의 link를 새 노드로 변경한다.
5
head를 새 노드로 변경한다.
주의: 일반 연결 리스트와 달리 마지막 노드의 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.link = node # 원형 유지 head = node return
NEW 다현 old head ... 지효 last step 2 step 4: last.link = node new head (step 5)
English
Steps to Insert Before the First Node
1
Create a new node and set its data.
2
Set the new node's link to the current head.
3
Find the last node (the node whose link points to head).
4
Change the last node's link to point to the new node.
5
Update head to point to the new node.
Caution: Unlike a regular linked list, the last node's link must also be updated! Otherwise the circular structure breaks.
Code: Head Insertion
def insertNode(findData, insertData): global memory, head, current, pre if head.data == findData: node = Node() node.data = insertData node.link = head # Find the last node last = head while last.link != head: last = last.link last.link = node # Maintain circular head = node return
NEW 다현 old head ... 지효 last step 2 step 4: last.link = node new head (step 5)

노드 삽입 - 중간/마지막 Insert Middle / End (Code05-05)

한국어
중간 노드 삽입

findData를 가진 노드를 찾으면 그 앞에 새 노드를 삽입한다. pre.link를 새 노드로, 새 노드의 link를 current로 연결한다.

current = head while current.link != head: pre = current current = current.link if current.data == findData: node = Node() node.data = insertData node.link = current pre.link = node return
마지막에 삽입 (데이터를 못 찾은 경우)

while 루프를 다 돌아도 찾지 못하면 마지막 노드 뒤에 추가한다.

# 마지막에 삽입 node = Node() node.data = insertData current.link = node node.link = head # 원형 유지!
English
Full insertNode Function
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.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 pre.link = node return node = Node() node.data = insertData current.link = node node.link = head

삽입 테스트 Insertion Test

한국어
테스트 케이스 1: Head 앞에 삽입
insertNode("다현", "화사") printNodes(head)

결과: 화사 다현 정연 쯔위 사나 지효

"다현" 앞에 "화사"를 삽입 → head가 "화사"로 변경됨

테스트 케이스 2: 중간 삽입
insertNode("사나", "솔라") printNodes(head)

결과: 화사 다현 정연 쯔위 솔라 사나 지효

"사나" 앞에 "솔라"를 삽입

테스트 케이스 3: 끝에 삽입 (못 찾은 경우)
insertNode("재남", "문별") printNodes(head)

결과: 화사 다현 정연 쯔위 솔라 사나 지효 문별

"재남"을 찾지 못해 "문별"이 마지막에 추가됨.

3번의 삽입 후 최종 상태: head 화사 다현 정연 쯔위 솔라 사나 지효 문별 circular link back to head
English
Test Case 1: Insert before head
insertNode("다현", "화사") printNodes(head)

Output: 화사 다현 정연 쯔위 사나 지효

Insert "화사" before "다현" -- head changes to "화사"

Test Case 2: Middle insertion
insertNode("사나", "솔라") printNodes(head)

Output: 화사 다현 정연 쯔위 솔라 사나 지효

Insert "솔라" before "사나"

Test Case 3: End Insertion (not found)
insertNode("재남", "문별") printNodes(head)

Output: 화사 다현 정연 쯔위 솔라 사나 지효 문별

"재남" not found, so "문별" is appended at the end.

Final state after 3 insertions: head 화사 다현 정연 쯔위 솔라 사나 지효 문별 circular link back to head

노드 삭제 - 첫 번째 노드 Delete Head (Code05-06)

한국어
첫 번째 노드 삭제 과정
1
current에 현재 head를 저장한다 (삭제 대상).
2
head를 다음 노드(head.link)로 이동시킨다.
3
마지막 노드를 찾는다 (link가 삭제할 노드를 가리키는 노드).
4
마지막 노드의 link를 새로운 head로 변경한다.
5
current(이전 head)를 삭제한다.
핵심: 삽입과 마찬가지로 마지막 노드의 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.link = head # 원형 유지 del(current) return
화사 DELETE 다현 new head ... 문별 last last.link = head (updated)
English
Steps to Delete the Head Node
1
Store the current head in current (the node to delete).
2
Move head to the next node (head.link).
3
Find the last node (the node whose link points to the node being deleted).
4
Change the last node's link to the new head.
5
Delete current (the old head).
Key Point: Just like insertion, the last node's link must be updated to maintain the circular structure.
Code: Head Deletion
def deleteNode(deleteData): global memory, head, current, pre if head.data == deleteData: current = head head = head.link # Find the last node last = head while last.link != current: last = last.link last.link = head # Maintain circular del(current) return
화사 DELETE 다현 new head ... 문별 last last.link = head (updated)

노드 삭제 - 중간/마지막 Delete Middle / End (Code05-06)

한국어
중간/마지막 노드 삭제

precurrent를 이동시키며 삭제 대상을 찾으면 pre.link = current.link로 연결을 우회한다.

current = head while current.link != head: pre = current current = current.link if current.data == deleteData: pre.link = current.link del(current) return
일반 연결 리스트와의 차이점: 종료 조건이 current.link != head이다. 마지막 노드를 삭제해도 pre.linkhead를 가리키게 되어 자동으로 원형이 유지된다.
Middle deletion: pre.link = current.link pre current next pre.link = current.link
English
Full deleteNode Function
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.link = 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
Difference from regular linked list: The termination condition is current.link != head. Even when deleting the last node, pre.link ends up pointing to head, so the circular structure is automatically maintained.
Middle deletion: pre.link = current.link pre current next pre.link = current.link

삭제 테스트 Deletion Test

한국어
삭제 전 리스트 상태

화사 다현 정연 쯔위 솔라 사나 지효 문별

테스트 1: Head 삭제
deleteNode("다현") printNodes(head)

결과: 화사 정연 쯔위 솔라 사나 지효 문별

테스트 2: 중간 노드 삭제
deleteNode("쯔위") printNodes(head)

결과: 화사 정연 솔라 사나 지효 문별

테스트 3: 다른 노드 삭제
deleteNode("지효") printNodes(head)

결과: 화사 정연 솔라 사나 문별

테스트 4: 존재하지 않는 노드 삭제
deleteNode("재남") printNodes(head)

결과: 화사 정연 솔라 사나 문별

"재남"은 리스트에 없으므로 아무것도 삭제되지 않는다.

모든 삭제 후 최종 상태: head 화사 정연 솔라 사나 문별
English
List State Before Deletion

화사 다현 정연 쯔위 솔라 사나 지효 문별

Test 1: Delete head
deleteNode("다현") printNodes(head)

Output: 화사 정연 쯔위 솔라 사나 지효 문별

Test 2: Delete middle node
deleteNode("쯔위") printNodes(head)

Output: 화사 정연 솔라 사나 지효 문별

Test 3: Delete another node
deleteNode("지효") printNodes(head)

Output: 화사 정연 솔라 사나 문별

Test 4: Delete last node
deleteNode("재남") printNodes(head)

Output: 화사 정연 솔라 사나 문별

"재남" is not in the list, so nothing is deleted.

Final state after all deletions: head 화사 정연 솔라 사나 문별

노드 검색 Node Search (Code05-07)

한국어
검색 알고리즘
1
head부터 시작하여 먼저 head의 데이터를 확인한다.
2
일치하면 해당 노드를 반환한다.
3
일치하지 않으면 다음 노드로 이동하며 순회한다.
4
한 바퀴를 다 돌아도 못 찾으면 빈 노드를 반환한다.
반환값 설계: 검색 실패 시 None 대신 빈 Node()를 반환하여 호출자가 .data에 안전하게 접근할 수 있도록 한다.
findNode 함수 (Code05-07)
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() # 빈 노드 반환
findNode("솔라") 검색 흐름 화사 X 정연 X 솔라 FOUND! 사나 문별 search path "재남" 검색 (못 찾은 경우): 모든 노드를 순회한 후 head로 돌아옴 -> 빈 Node() 반환 (data = None)
English
Search Algorithm
1
Start from head and first check head's data.
2
If it matches, return that node.
3
If not, move to the next node and continue traversing.
4
If the entire list is traversed without finding it, return an empty node.
Return value design: On search failure, returning an empty Node() instead of None allows the caller to safely access .data.
findNode Function (Code05-07)
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() # return empty node
Search flow for findNode("솔라") 화사 X 정연 X 솔라 FOUND! 사나 문별 search path Search for "재남" (not found): Traverses all nodes, returns to head -> returns empty Node() (data = None)

검색 테스트 Search Test

한국어
테스트 1: Head 노드 검색
node = findNode("다현") print(node.data)

결과: 다현

첫 번째 노드이므로 바로 반환된다.

테스트 2: 중간 노드 검색
node = findNode("쯔위") print(node.data)

결과: 쯔위

순회 중 발견되어 해당 노드가 반환된다.

테스트 3: 존재하지 않는 노드 검색
node = findNode("재남") print(node.data)

결과: None

"재남"은 리스트에 존재하지 않는다. 전체 순회 후 빈 Node()가 반환된다. 해당 노드의 data 속성은 None이다.

검색 함수 요약
경우 반환값 data
head에서 발견 head 노드 실제 데이터
중간에서 발견 일치하는 노드 실제 데이터
못 찾음 빈 Node() None
English
Test 1: Search for head node
node = findNode("다현") print(node.data)

Output: 다현

It is the first node, so it is returned immediately.

Test 2: Search for middle node
node = findNode("쯔위") print(node.data)

Output: 쯔위

Found during traversal and the matching node is returned.

Test 3: Search for non-existent node
node = findNode("재남") print(node.data)

Output: None

"재남" does not exist in the list. After a full traversal, an empty Node() is returned. Its data attribute is None.

Search Summary
Case Return data
Found at head head node actual data
Found in middle matching node actual data
Not found empty Node() None

Part 2 연습문제 Practice Problems

한국어
연습문제 1

다음 원형 연결 리스트에서 insertNode("정연", "휘인")을 실행하면 리스트는 어떻게 변하는가? 각 단계의 포인터 변화를 그림으로 그려라.

리스트: 다현 -> 정연 -> 쯔위 -> 사나 -> 지효 -> (다현)

연습문제 2

원형 연결 리스트에서 첫 번째 노드를 삭제할 때 마지막 노드의 link를 갱신하지 않으면 어떤 문제가 발생하는지 설명하라. printNodes 함수의 동작과 연관 지어 서술하시오.

연습문제 3

findNode 함수를 수정하여 대상을 찾기 전까지 방문한 노드 수를 세도록 하라. 대상을 찾지 못하면 빈 노드 대신 -1을 반환하라.

def findNodeCount(findData): # 여기에 구현을 작성하세요 # 반환: (node, count) 튜플 # 못 찾은 경우: (None, -1) pass

힌트: current가 다음 노드로 이동할 때마다 증가하는 카운터 변수를 추가하라. head 노드부터 1로 시작한다.

팁: 연습문제 1과 2의 경우, 먼저 종이에 노드 다이어그램을 그려보세요. 포인터 변화를 단계별로 추적하는 것이 원형 연결 리스트 연산을 이해하는 가장 좋은 방법입니다.
English
Practice Problem 1

Given the following circular linked list, what happens when insertNode("정연", "휘인") is executed? Draw the pointer changes at each step.

List: 다현 -> 정연 -> 쯔위 -> 사나 -> 지효 -> (다현)

Practice Problem 2

Explain what problem occurs if the last node's link is not updated when deleting the first node in a circular linked list. Describe in relation to how the printNodes function behaves.

Practice Problem 3

Modify the findNode function to count how many nodes were visited before finding the target. If the target is not found, return -1 instead of an empty node.

def findNodeCount(findData): # Write your implementation here # Return: (node, count) tuple # If not found: (None, -1) pass

Hint: Add a counter variable that increments each time current moves to the next node. Start counting from 1 for the head node.

Tip: For problems 1 and 2, draw the node diagrams on paper first. Tracing through the pointer changes step by step is the best way to understand circular linked list operations.
03
Part 3
원형 연결 리스트의 응용
Applications of Circular Linked List
실전 응용 사례와 종합 실습, 전체 소스코드를 학습합니다

Code05-08: 홀짝 카운트 응용

Odd-Even Count Application
한국어
프로그램 개요

랜덤 숫자 7개를 원형 연결 리스트에 저장한 후, 홀수와 짝수의 개수를 세고 소수(적은 쪽)의 값을 음수로 변환합니다.

1
랜덤 정수 7개 생성 → 원형 연결 리스트 구축
2
countOddEven() → 홀수/짝수 개수 반환
3
makeZeroNumber() → 적은 쪽을 음수로 변환
def countOddEven(): global memory, head, current, pre odd, even = 0, 0 if head == None: return False current = head while True: if current.data % 2 == 0: even += 1 else: odd += 1 if current.link == head: break current = current.link return odd, even
핵심 로직: odd > even이면 소수 쪽의 나머지는 1(짝수)이므로 짝수 값을 음수로 변환합니다. while True + break 패턴으로 모든 노드를 빠짐없이 처리합니다.
실행 결과 예시:
45 12 78 33 91 56 27
홀수 --> 4   짝수 --> 3
45 -12 -78 33 91 -56 27
English
Program Overview

Generate 7 random numbers, store them in a circular linked list, count odd and even numbers, then negate the minority group.

1
Generate 7 random integers → build circular linked list
2
countOddEven() → return odd/even counts
3
makeZeroNumber() → negate the minority group
def makeZeroNumber(odd, even): if odd > even: reminder = 1 # minority = even else: reminder = 0 # minority = odd current = head while True: if current.data % 2 == reminder: current.data *= -1 if current.link == head: break current = current.link
Key Logic: If odd > even, the minority remainder is 1 (even numbers), so we negate even values. The while True + break pattern ensures every node is processed.
Example Output:
45 12 78 33 91 56 27
Odd --> 4   Even --> 3
45 -12 -78 33 91 -56 27

while True + break 패턴

The while True + break Pattern
한국어
문제점: while current.link != head 패턴은 마지막 노드의 데이터를 처리하지 못합니다! 조건 검사가 데이터 처리보다 먼저 실행되기 때문입니다.
잘못된 패턴 (마지막 노드 누락)
current = head while current.link != head: # current 처리 process(current.data) # 마지막 노드 건너뜀! current = current.link
올바른 패턴 (모든 노드 처리)
current = head while True: process(current.data) # 먼저 처리 if current.link == head: break # 그 다음 탈출 검사 current = current.link
X 잘못된 패턴 start link != head? Y process() N: last node skipped! O 올바른 패턴 start process() link == head? Y break N: next node
경험 법칙: 원형 연결 리스트에서 모든 노드의 데이터를 처리해야 할 때(카운트, 수정 등)는 while True + break 패턴을 사용하세요. while current.link != head는 위치를 찾을 때(데이터 처리 없이)만 사용합니다.
패턴처리 노드 수사용 상황
while link != headN - 1위치 탐색
while True + breakN (전부)전체 데이터 처리
English
Core Issue: In a circular list, the while current.link != head condition checks before processing. When current is the last node, current.link == head is true, so the loop exits without processing that last node.
Solution: Process First, Check After

The while True + break pattern reverses the order:

  1. Process the current node's data
  2. Check if this is the last node
  3. If last → break; otherwise → advance

This guarantees every node in the circular list is visited and processed exactly once.

X Wrong Pattern start link != head? Y process() N: last node skipped! O Correct Pattern start process() link == head? Y break N: next node
Rule of Thumb: Whenever you need to process data in every node of a circular linked list (counting, modifying, etc.), use the while True + break pattern. Use while current.link != head only when traversing to find a position (not processing data).
PatternNodes ProcessedUse Case
while link != headN - 1Finding a position
while True + breakN (all)Processing all data

EX05-01: 편의점 거리순 정렬

Store Distance Sorting Application
한국어
문제 설명

10개의 편의점이 랜덤 좌표에 위치합니다. 원점(0, 0)에서의 거리를 기준으로 가까운 순서대로 정렬하여 원형 연결 리스트에 삽입합니다.

1
랜덤 (x, y) 좌표(1~100)로 편의점 10개 생성
2
거리 계산: sqrt(x*x + y*y)
3
각 편의점을 원형 리스트의 올바른 정렬 위치에 삽입
핵심 알고리즘: 새 노드를 삽입할 때 거리를 비교하여 올바른 위치에 삽입 → 삽입 정렬(Insertion Sort) 방식
삽입 경우의 수
# 경우 1: 빈 리스트 head = node; node.link = head # 경우 2: 새 노드가 head보다 가까운 경우 node.link = head last.link = node # tail 업데이트 head = node # 경우 3: 중간 삽입 pre.link = node node.link = current # 경우 4: 끝에 삽입 current.link = node node.link = head
x y O(0,0) A B C D E F dist = sqrt(x*x+y*y) Near (close) Medium Far
자료 구조: 각 노드는 튜플을 저장합니다: ('A', x, y) 여기서 'A'는 편의점 이름, x, y는 좌표입니다.
English
Problem Description

10 convenience stores are placed at random (x, y) coordinates. Sort them by Euclidean distance from the origin and build a circular linked list in ascending order.

1
Generate 10 stores with random (x, y) coordinates (1~100)
2
Calculate distance: sqrt(x*x + y*y)
3
Insert each store into the correct sorted position in the circular list
Core Algorithm: Compare distances when inserting a new node to find the correct position → Insertion Sort approach
Insertion Cases
# Case 1: Empty list head = node; node.link = head # Case 2: New node closer than head node.link = head last.link = node # update tail head = node # Case 3: Insert in middle pre.link = node node.link = current # Case 4: Insert at end current.link = node node.link = head
x y O(0,0) A B C D E F dist = sqrt(x*x+y*y) Near (close) Medium Far
Data Structure: Each node stores a tuple: ('A', x, y) where 'A' is the store name and x, y are coordinates.

EX05-01: 전체 코드

Full Code - Store Distance Sorting
한국어
import random import math class Node(): def __init__(self): self.data = None self.link = None def printStores(start): current = start if current == None: return while current.link != head: current = current.link x, y = current.data[1:] print(current.data[0], '편의점, 거리:', math.sqrt(x*x + y*y)) print() def makeStoreList(store): global memory, head, current, pre node = Node() node.data = store memory.append(node) if head == None: head = node node.link = head return # 새 노드의 거리 계산 nodeX, nodeY = node.data[1:] nodeDist = math.sqrt( nodeX*nodeX + nodeY*nodeY) # head보다 가까우면 head 교체 headX, headY = head.data[1:] headDist = math.sqrt( headX*headX + headY*headY) if headDist > nodeDist: node.link = head last = head while last.link != head: last = last.link last.link = node head = node return
실행 결과 예시:
B 편의점, 거리: 28.28...
A 편의점, 거리: 42.43...
E 편의점, 거리: 56.57...
... (거리순 정렬)
핵심 포인트: makeStoreList()는 유클리드 거리를 비교하여 정렬 삽입을 구현합니다. head 앞 삽입, 중간 삽입, 끝 삽입의 세 가지 경우를 처리합니다.
English
# Insert in middle or end current = head while current.link != head: pre = current current = current.link currX, currY = current.data[1:] currDist = math.sqrt( currX*currX + currY*currY) if currDist > nodeDist: pre.link = node node.link = current return current.link = node node.link = head memory = [] head, current, pre = None, None, None if __name__ == "__main__": storeArray = [] storeName = 'A' for _ in range(10): store = (storeName, random.randint(1, 100), random.randint(1, 100)) storeArray.append(store) storeName = chr(ord(storeName)+1) for store in storeArray: makeStoreList(store) printStores(head)
Expected Output (example):
B store, dist: 28.28...
A store, dist: 42.43...
E store, dist: 56.57...
... (sorted by distance)
Key Point: makeStoreList() implements sorted insertion by comparing Euclidean distances. It handles three cases: insert before head, insert in the middle, and insert at the tail.

EX05-02: 이중 연결 리스트

Doubly Linked List
한국어
이중 연결 리스트 개념

각 노드가 이전 노드(plink)다음 노드(nlink) 두 개의 링크를 가집니다. 양방향 순회가 가능합니다.

Node2 Structure: plink 다현 nlink None 정연 쯔위 ... head nlink (forward) plink (backward)
class Node2(): def __init__(self): self.plink = None # 이전 노드 self.data = None # 데이터 self.nlink = None # 다음 노드
실행 결과:
Forward --> 다현 정연 쯔위 사나 지효
Backward --> 지효 사나 쯔위 정연 다현
English
Doubly Linked List Concept

Each node has two links: plink (previous) and nlink (next). This enables bidirectional traversal.

Node2 Structure: plink 다현 nlink None 정연 쯔위 ... head nlink (forward) plink (backward)
def printNodes(start): current = start if current.nlink == None: return print("Forward -->", end=' ') print(current.data, end=' ') while current.nlink != None: current = current.nlink print(current.data, end=' ') print() print("Backward -->", end=' ') print(current.data, end=' ') while current.plink != None: current = current.plink print(current.data, end=' ') # Building the doubly linked list dataArray = ["다현", "정연", "쯔위", "사나", "지효"] node = Node2() node.data = dataArray[0] head = node for data in dataArray[1:]: pre = node node = Node2() node.data = data pre.nlink = node # forward link node.plink = pre # backward link
Output:
Forward --> 다현 정연 쯔위 사나 지효
Backward --> 지효 사나 쯔위 정연 다현

Part 3 연습문제

Part 3 Practice Problems
한국어
연습문제 1

원형 연결 리스트에 랜덤 정수 10개를 저장한 후, 3의 배수의 개수와 합계를 구하는 함수 countMultiplesOf3()를 작성하시오.

힌트: while True + break 패턴을 사용하고, current.data % 3 == 0 조건으로 판별합니다.
연습문제 2

이중 연결 리스트에 5명의 이름을 저장한 후, 특정 이름을 검색하여 그 이름의 앞 사람과 뒷 사람을 출력하는 함수를 작성하시오.

힌트: 찾은 노드의 plink.datanlink.data를 활용합니다. 첫 번째/마지막 노드일 경우의 예외 처리도 해야 합니다.
연습문제 3

Code05-08의 홀짝 카운트 예제를 수정하여, 적은 쪽을 음수로 만드는 대신 리스트에서 삭제하는 프로그램을 작성하시오.

힌트: 삭제 시 pre 노드의 linkcurrent.link로 변경합니다. head 노드 삭제 시 특별 처리가 필요합니다.
English
Practice 1

Store 10 random integers in a circular linked list, then write a function countMultiplesOf3() that returns the count and sum of multiples of 3.

Hint: Use the while True + break pattern with condition current.data % 3 == 0.
Practice 2

Store 5 names in a doubly linked list and write a function that searches for a name and prints the previous and next person.

Hint: Use the found node's plink.data and nlink.data. Handle edge cases for the first and last nodes.
Practice 3

Modify the odd-even count example (Code05-08) to delete the minority nodes from the list instead of negating them.

Hint: When deleting, set pre.link = current.link. Special handling is needed when deleting the head node.

5장 학습 정리

Chapter 5 Summary
한국어
핵심 개념 정리
  • 원형 연결 리스트: 마지막 노드의 link가 head를 가리키는 구조
  • 생성: 노드 생성 후 마지막 노드의 link를 head로 설정
  • 삽입: head 앞, 중간, 끝 세 가지 경우 처리
  • 삭제: head 삭제 시 tail의 link 업데이트 필수
  • 검색: while True + break 패턴으로 모든 노드 탐색
  • 이중 연결 리스트: plink와 nlink로 양방향 순회
단순 연결 리스트 A B C None 원형 연결 리스트 A B C 이중 연결 리스트 A B
특징 단순 원형 이중
방향 순방향만 순방향 (순환) 양방향
마지막 노드 link None head None
노드당 링크 수 1 1 2
끝 감지 link == None link == head nlink == None
메모리 적음 적음 많음
역방향 순회 불가능 불가능 가능
English
Key Concepts Summary
  • Circular Linked List: Last node's link points back to head
  • Creation: Set last node's link to head after building
  • Insertion: Handle before-head, middle, and end cases
  • Deletion: Update tail's link when deleting head
  • Search: Use while True + break to visit all nodes
  • Doubly Linked: plink and nlink enable bidirectional traversal
Simple Linked List A B C None Circular Linked List A B C Doubly Linked List A B
Feature Simple Circular Doubly
Direction Forward only Forward (loop) Both ways
Last node link None head None
Links per node 1 1 2
End detection link == None link == head nlink == None
Memory Low Low Higher
Reverse traversal Not possible Not possible Possible

전체 소스코드: Code05-04

Complete Source: Circular List Creation
한국어 - 전체 코드
프로그램 설명

이름 배열로부터 원형 연결 리스트를 생성하고, 원형 구조를 순회하며 모든 노드를 출력합니다.

1
Node 클래스: 각 노드는 datalink 필드를 가짐
2
첫 번째 노드: head 노드를 생성하고, link = head (자기 자신을 가리킴)
3
나머지 노드: 이전 노드를 새 노드에 연결, 새 노드의 link는 head를 가리킴
4
printNodes: start부터 출력, current.link == start까지 순회
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() 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)
실행 결과:
다현 정연 쯔위 사나 지효
핵심 포인트: 모든 새 노드의 link는 항상 head를 가리키며, 각 단계에서 원형 구조를 유지합니다. memory 리스트는 가비지 컬렉션을 방지합니다.
English - Explanation
Program Description

Creates a circular linked list from an array of names and prints all nodes by traversing the circular structure.

1
Node class: Each node has data and link fields
2
First node: Create head node, set link = head (points to itself)
3
Remaining nodes: Link previous node to new node, new node's link points to head
4
printNodes: Print from start, traverse until current.link == start
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() 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)
Expected Output:
다현 정연 쯔위 사나 지효
Key Point: Every new node's link always points to head, maintaining the circular structure at each step. The memory list prevents garbage collection.

전체 소스코드: Code05-05

Complete Source: Node Insertion
한국어 - 전체 코드
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.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 pre.link = node return node = Node() node.data = insertData current.link = node node.link = head
실행 결과:
다현 정연 쯔위 사나 지효
화사 다현 정연 쯔위 사나 지효
화사 다현 정연 솔라 쯔위 사나 지효
화사 다현 정연 솔라 쯔위 사나 지효 문별
세 가지 경우:
1. head 앞 삽입 → head와 마지막 노드의 link 업데이트
2. 중간 삽입 → pre.link와 node.link 조정
3. 미발견 → 끝에 추가, head로 link 연결
English - Explanation
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)
Expected Output:
다현 정연 쯔위 사나 지효
화사 다현 정연 쯔위 사나 지효
화사 다현 정연 솔라 쯔위 사나 지효
화사 다현 정연 솔라 쯔위 사나 지효 문별
Three Cases:
1. Insert before head → update head and last node's link
2. Insert in middle → adjust pre.link and node.link
3. Not found → append at end, link back to head

전체 소스코드: Code05-06

Complete Source: Node Deletion
한국어 - 전체 코드
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 deleteNode(deleteData): global memory, head, current, pre if head.data == deleteData: current = head while current.link != head: current = current.link current.link = head.link head = head.link return current = head while current.link != head: pre = current current = current.link if current.data == deleteData: pre.link = current.link return
실행 결과:
다현 정연 쯔위 사나 지효
다현 정연 사나 지효
정연 사나 지효
정연 사나
두 가지 경우:
1. head 삭제 → 마지막 노드를 찾아 link를 head.link로 변경, head를 앞으로 이동
2. 중간/끝 삭제 → pre.link = current.link로 삭제 노드를 우회
English - Explanation
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) deleteNode("쯔위") printNodes(head) deleteNode("다현") printNodes(head) deleteNode("지효") printNodes(head)
Expected Output:
다현 정연 쯔위 사나 지효
다현 정연 사나 지효
정연 사나 지효
정연 사나
Two Cases:
1. Delete head → find last node, update its link to head.link, move head forward
2. Delete middle/end → set pre.link = current.link to bypass the deleted node

전체 소스코드: Code05-07

Complete Source: Node Search
한국어 - 전체 코드
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 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 None memory = [] head, current, pre = None, None, None dataArray = ["다현", "정연", "쯔위", "사나", "지효"]
실행 결과:
다현 정연 쯔위 사나 지효
쯔위 found
not found
검색 로직:
1. head를 먼저 확인
2. while current.link != head로 순회
3. 찾으면 노드 반환, 없으면 None 반환

참고: 카운트/처리와 달리, 검색은 head를 별도로 확인하고 찾는 즉시 반환하므로 단순 while 패턴을 사용할 수 있습니다.
English - Explanation
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) # Search for existing node result = findNode("쯔위") if result != None: print(result.data, 'found') # Search for non-existing node result = findNode("없음") if result != None: print(result.data, 'found') else: print('not found')
Expected Output:
다현 정연 쯔위 사나 지효
쯔위 found
not found
Search Logic:
1. Check head first
2. Traverse with while current.link != head
3. Return the node if found, None if not

Note: Unlike counting/processing, search can use the simple while pattern because we check head separately and return immediately upon finding the target.

전체 소스코드: Code05-08

Complete Source: Odd-Even Application
한국어 - 전체 코드
import random 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 countOddEven(): global memory, head, current, pre odd, even = 0, 0 if head == None: return False current = head while True: if current.data % 2 == 0: even += 1 else: odd += 1 if current.link == head: break current = current.link return odd, even
English - Full Code (continued)
def makeZeroNumber(odd, even): if odd > even: reminder = 1 else: reminder = 0 current = head while True: if current.data % 2 == reminder: current.data *= -1 if current.link == head: break current = current.link memory = [] head, current, pre = None, None, None if __name__ == "__main__": dataArray = [] for _ in range(7): dataArray.append( random.randint(1, 100)) 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) oddCount, evenCount = countOddEven() print('Odd -->', oddCount, '\t', 'Even -->', evenCount) makeZeroNumber(oddCount, evenCount) printNodes(head)

전체 소스코드: EX05-01

Complete Source: Store Distance Sorting
한국어 - 전체 코드
import random import math class Node(): def __init__(self): self.data = None self.link = None def printStores(start): current = start if current == None: return while current.link != head: current = current.link x, y = current.data[1:] print(current.data[0], '편의점, 거리:', math.sqrt(x*x + y*y)) print() def makeStoreList(store): global memory, head, current, pre node = Node() node.data = store memory.append(node) if head == None: head = node node.link = head return nodeX, nodeY = node.data[1:] nodeDist = math.sqrt( nodeX*nodeX + nodeY*nodeY) headX, headY = head.data[1:] headDist = math.sqrt( headX*headX + headY*headY)
English - Full Code (continued)
if headDist > nodeDist: node.link = head last = head while last.link != head: last = last.link last.link = node head = node return current = head while current.link != head: pre = current current = current.link currX, currY = current.data[1:] currDist = math.sqrt( currX*currX + currY*currY) if currDist > nodeDist: pre.link = node node.link = current return current.link = node node.link = head memory = [] head, current, pre = None, None, None if __name__ == "__main__": storeArray = [] storeName = 'A' for _ in range(10): store = (storeName, random.randint(1, 100), random.randint(1, 100)) storeArray.append(store) storeName = chr( ord(storeName) + 1) for store in storeArray: makeStoreList(store) printStores(head)
1 / 39