LinkedList

데이터를 링크로 연결해서 관리하는 자료구조

자료의 순서는 정해져 있지만, 메모리상의 연속성은 보장되지 않는다

노드라는 구조체로 이루어진 자료구조, 노드는 데이터와 다음 데이터의 주소를 담고 있다.

  • 장점
    • 데이터 공간을 미리 할당 받지 않아도 된다
    • 리스트 길이가 가변적이라서 추가,삭제가 용이하다
  • 단점
    • 주소를 저장하는 추가 공간이 필요하다.
    • 연결 정보를 찾는 시간이 필요하기 때문에 접근 속도가 상대적으로 느리다
    • 데이터 추가, 삭제 시 앞 뒤 데이터의 연결을 재구성하는 작업이 필요하다

노드 : 데이터 저장 단위로, 값 + 포인터로 구성

LinkedList 연산

작업을 수행하는 위치(head, 중간, tail)에 따라 연결 작업이 다르다.

 

데이터 추가

  • head로 추가할 때
    • 추가할 데이터를 담을 노드 생성
    • 링크 연결 작업
    • head 이전 작업
  • tail에 추가할 때
    • 추가할 데이터를 담을 노드 생성
    • head로부터 끝노드까지 순회
    • 끝 노드의 포인터에 생성한 노드의 주소 연결
  • 중간에 추가할 때
    • 추가할 데이터를 담을 노드 생성
    • head로부터 데이터 추가 위치 직전 노드까지 순회
    • 링크 연결 작업(이전노드의 포인터를 지금 노드에, 지금 노드의 포인터를 다음 노드의 위치로 연결)

데이터 삭제

  • head 위치의 노드 삭제할 때
    • 삭제 대상 노드 지정(delete_node)
    • head 이전 작업
    • delete_node 삭제
  • tail 위치의 노드 삭제할 때
    • head로 부터 가장 끝까지 순회
    • 끝 노드 삭제
    • 삭제 이전 노드의 링크 처리
  • 중간에 있는 노드 삭제할 때
    • head로부터 삭제 대상 노드까지 순회 및 해당 노드(delete_node) 지정
    • 삭제 대상 이전/이후 노드의 링크 연결 작업
    • delete_node 삭제

구현

참고 블로그

  • 노드 생성
class Node :
    def __init__(self, data):
        self.data = data
        self.next = None
  • 가장 오른쪽에 노드 추가하기
# 가장 오른쪽에 노드 추가하기 
    def append(self, data):
        cur = self.head
        while cur.next is not None:
            cur = cur.next
        cur.next = None(data)
  • 전체 데이터 출력
# 전체 데이터 출력  
    def print_all(self):
        cur = self.head
        while cur.next is not None:
            print(cur.data, end = ' ')
            cur = cur.next
  • 원하는 노드 찾기
def get_node(self, index):
        count = 0
        node = self.head
        while count < index:
            count += 1
            node = node.next
        return node
  • 중간에 노드 삽입 (헤드인 경우 항상 고려하기!)
def add_node(self, index, value) :
        new_node = Node(value)
        if index == 0:
            new_node.next = self.head
            self.head = new_node
            return
        
        node = self.get_node(index - 1)
        next_node = node.next
        node.next = new_node
        new_node.next = next_node
  • 노드 삭제 (헤드인 경우 항상 고려하기!)
def delete_node(self, index):
        if index == 0:
            self.head = self.head.next
            
        prev_node = self.get_node(index - 1)    
        prev_node.next = self.get_node(index) .next (prev_node.next.next)

Queue

선입선출의 자료구조, 먼저 들어온 데이터가 먼저 나가는 구조

입력 순서대로 데이터 처리가 필요할 때 사용

사용되는 곳 : 프린터 출력 대기열, bfs

연산 : 삽입(Enqueue), 추출(Dequeue)

Stack

후입선출의 자료구조, 마지막에 들어온 데이터가 먼저 나가는 구조

데이터가 입력된 순서의 역순으로 처리되어야 할 때 사용

사용되는 곳 : 함수 콜 스택, 수식 계산, 인터럽트 처리 등

연산 : 추가(Push), 추출(Pop)

'알고리즘 &자료구조' 카테고리의 다른 글

[자료구조/Python] 복습 3. Deque  (0) 2022.12.22
[자료구조/Python] 복습 2. LinkedList  (0) 2022.12.22
[알고리즘] Union -Find  (0) 2022.07.17
[알고리즘] 백트래킹  (0) 2021.11.10
[알고리즘] 허프만 코딩  (0) 2021.11.09

백준 공항 문제를 풀다가 Union - Find가 무엇인지 모르겠어서 공부한 내용을 정리해보려 한다. 

 

Union - Find란?

Disjoint set을 표현할 때 사용하는 알고리즘 

 

트리구조를 이용해 구현하는 것이 제일 효율적이다 

 

함수

  • union(x, y) : x가 속한 집합과 y가 속한 집합을 합친다 
  • find(x) : x가 속한 집합의 루트노드 값을 반환한다 
  • 재귀함수를 이용하는데, 루트노드가 들어온 경우는 그거 그대로 반환하고, 
  • 아닌경우는 부모노드를 계속 찾아서 반환한다 

 

초기화는 

parents=[i for i in range(g+1)] 방식으로 하면 된다 

 

공항 문제에서는 1번부터 gi까지의 게이트 중 빈 게이트를 이용하면 되므로, i번째 비행기의 게이트 값이 부모 루트가 되어서, 

그거에 속한 애들을 구하는 알고리즘이 필요해서 union - find를 이용한 것이라고 이해했다. 

그래서 같은 게이트 번호를 가진 비행기들을 최대한 도킹시킬 수 있다. 

 

참고 블로그 : https://gmlwjd9405.github.io/2018/08/31/algorithm-union-find.html

  • 공부한 날짜: 2021. 11. 10 / 전체 1차 공부 끝!!!!

 

1. 백트래킹

: 여러 후보해 중에서 특정 조건을 충조고시키는 모든 해를 찾는 알고리즘 

백트래킹이 다루는 문제들은 해가 하나 이상 존재한다

후보해: 해가 될 수 있는 가능성을 가진 부분해의 조합

모든해: 문제의 정답을 모아놓은 것

목적: '진짜 해'를 효율적으러 찾는 것 

 

2. 백트래킹을 이용한 미로찾기 

 

  • 규칙

ㄱ. 갈래 길이 나오면 무조건 왼쪽 길부터 들어간다

ㄴ. 막다른 곳이 나오면 갈래 길목으로 되돌아 나와 다음 길을 시도한다

ㄷ. ㄱ~ㄴ 과정을 목표 지점에 도달하거나 모든 경로를 다 탐색할 때까지 계속한다

 

  • 깊이 우선 탐색과 다른점

: 깊이 우선 탐색은 모든 노드를 방문하는 것이 목적이고, 백트래킹은 해를 찾는 것이 목적이기 때문에 모든 노드를 방문할 필요가 없다

(해를 찾는 비용을 줄이기 위해 최대한 방문할 노드의 수를 최소화하는 것이 중요)

 

  • 구현 원리

(1) 부분해 계산 

(2) 다음 부분 후보해 목록 확인(여기서 재귀호출을 이용한다)

(3) 각 부분 후보해 계산 

 

  • 백트래킹이 처리해야하는 경우

(1) 현재 시도 중인 부분 후보해가 해가 될 수 있는 조건을 불만족 시킬때

(2) 최종해를 확보한 경우 (후보해가 조건을 만족한 경우)

 

백트래킹 구현방법: 위의 두가지 경우를 만나면 그 함수를 반환하는 것으로 백트래킹이 이루어진다 

 

 

  • 알고리즘 구현 

ㄱ. 시작점을 현재 위치로 지정하고, 이동방향을 북으로 설정

ㄴ. 현 위치에서 가고자 하는 방향에 대해 이동 가능한지를 확인. 벽과 지나왔던 길은 이동가능한 길이 아님

ㄷ. ㄴ 과정에서 현재 방향에 대해 이동가능한 방향임이 확인되면 그곳으로 이동. 이동이 불가능한 방향으로 판정되면 방향(북-님-동-서)을 바꾸어서 다시 ㄴ을 시행한다. 현 위치에서 어떤 방향으로도 이동할 수 없ㅇㅁ이 확인되면 이전 위치로 되돌아감

ㄹ. 출구를 찾거나 미로 내의 모든 길을 방문할 때까지 ㄴ,ㄷ과정을 반복 

 

*ㄴ과정은 GetNextStep(),ㄷ과정은 MoveTo()라는 함수로 구현함 

 

 

2. N개의 퀸

: 퀸 N개를 NxN 크기의 체스판 안에 서로를 공격할 수 없게 배치하는 모든 경우를 구하는 문제 

+ Recent posts