사전 조건

- 각각의 노드로 연결되어 있는 트리구조
- 깊이를 우선으로 탐색한다.
- Stack를 사용

동작 방식

- 시작 노드를 탐색하고 방문처리.
- 시작 노드의 연결을 Stack에 담아준다.
- Stack에 마지막에 넣은 값 중에서 방문하지 않은 노드를 찾아 이동한다.
- 이동한 노드를 시작노드로 잡고 위 작업을 반복해준다,
- 탐색이 완료된 순서대로 출력한다.

예시 소스 결과

[1, 2, 4, 6, 5, 3, 9, 7, 8]

시간 복잡도

O(V + E)
    - 인접 리스트 인경우
    - 모든 정점에 대해 존재하는 간선만 탐색
    - 정점의 수(Vertex) + 간선의 수(Edge)

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 29
    @ Update : 2020. 01. 29
    @ Description : DFS, Depth-First Search (깊이우선탐색)
    '''

    def fn_depthfirst_search(dict_input, int_start, list_end):
        '''
            @Description: DFS, Depth-First Search (깊이우선 탐색)

            @Arguments Example
                # 0~10 사이의 정수라 가정
                dict_input = {
                    1:[2, 3],
                    2:[1, 4, 5, 7],
                    3:[1, 5, 9],
                    4:[2, 6],
                    5:[2, 3, 7, 8],
                    6:[4],
                    7:[5, 2],
                    8:[5],
                    9:[3]
                }
        '''
        list_end.append(int_start)
        for int_index in range(len(dict_input[int_start])):
            if dict_input[int_start][int_index] not in list_end:
                fn_depthfirst_search(dict_input, dict_input[int_start][int_index], list_end)
        return list_end


    if __name__ == "__main__":
        list_fn_depthfirst_search_param={
            1:[2, 3],
            2:[1, 4, 5, 7],
            3:[1, 5, 9],
            4:[2, 6],
            5:[2, 3, 7, 8],
            6:[4],
            7:[5, 2],
            8:[5],
            9:[3]
        }
        print(fn_depthfirst_search(list_fn_depthfirst_search_param, 1, []))

'알고리즘 > 탐색' 카테고리의 다른 글

1. 너비우선 탐색 (Breadth-First Search)  (0) 2020.01.29

사전 조건

- 각각의 노드로 연결되어 있는 트리구조
- 시작점과 가까운것 위주의 탐색 기법
- 최단 경로 찾기, 미로 찾기에서 사용
 -Queue를 사용

동작 방식

- 시작 노드를 탐색하고 방문처리.
- 시작 노드의 연결을 Queue에 담아준다.
- Queue에서 하나씩 꺼낸 값을 시작노드로 설정하고 위 작업을 반복해준다.
- 작업을 반복할 때 이미 탐색한 노드는 탐색하지 않는다.
- 탐색이 완료된 순서대로 출력한다.

동작 순서 예시

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 7]
[1, 2, 3, 4, 5, 7, 9]
[1, 2, 3, 4, 5, 7, 9, 6]
[1, 2, 3, 4, 5, 7, 9, 6, 8]

시간 복잡도

O(V + E)
    - 인접 리스트 인경우
    - 모든 정점에 대해 존재하는 간선만 탐색
    - 정점의 수(Vertex) + 간선의 수(Edge)

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 29
    @ Update : 2020. 01. 29
    @ Description : BFS, Breadth-First Search (너비우선탐색)
    '''
    import queue


    def fn_breadthfirst_search(dict_input):
        '''
            @Description: BFS, Breadth-First Search (너비우선 탐색)

            @Arguments Example
                # 0~10 사이의 정수라 가정
                dict_input = {
                    1:[2, 3],
                    2:[1, 4, 5, 7],
                    3:[1, 5, 9],
                    4:[2, 6],
                    5:[2, 3, 7, 8],
                    6:[4],
                    7:[5, 2],
                    8:[5],
                    9:[3]
                }
        '''
        responce = []
        list_end = [1]
        queue_list = queue.Queue()
        queue_list.put(1)

        while queue_list.qsize() >= 1:
            int_value = queue_list.get()
            for int_resource_index in range(len(dict_input[int_value])):
                if dict_input[int_value][int_resource_index] not in list_end:
                    queue_list.put(dict_input[int_value][int_resource_index])
                    list_end.append(dict_input[int_value][int_resource_index])
            responce.append(int_value)
            print(responce)

    if __name__ == "__main__":
        list_fn_breadthfirst_search_param={
            1:[2, 3],
            2:[1, 4, 5, 7],
            3:[1, 5, 9],
            4:[2, 6],
            5:[2, 3, 7, 8],
            6:[4],
            7:[5, 2],
            8:[5],
            9:[3]
        }
        print(fn_breadthfirst_search(list_fn_breadthfirst_search_param))

'알고리즘 > 탐색' 카테고리의 다른 글

2. 깊이우선탐색(Depth-First Search)  (0) 2020.01.30

사전 조건

- 배열의 인자 값의 범위가 작을 때 적합하다.

동작 방식

- 배열의 인자를 하나씩 꺼낸 인자값과 새로운 배열의 인덱스 값이 같은 새로운 배열의 인자값을 1식 증가시켜준다.

장점

- 배열의 인자 값의 범위가 적을 경우 매우 빠른 속도를 낼 수 있다.
- 그러나 배열의 크기가 작고 인자값의 크기가 큰 경우 부적합 할 수 있다.

시간 복잡도

O(n) - 최대 값이 주어졌다면
    - 배열의 인자 값의 갯수 만큼 업데이트 하기 때문에 O(n)
    - 새로운 배열의 인자값들의 개수(k)를 합해야 하기 때문에 O(k)
    - 원소들을 새로운 배열에 넣어야 하기 때문에 O(n)
    - 따라서 O(2n + k) 간단하게 O(2n + k)
    - 그러나 k값 즉 인자의 최대 값이 작다면 O(n)으로 표현 할 수 있다.

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 28
    @ Update : 2020. 01. 28
    @ Description : Counting sort (계수 정렬)
    '''


    def fn_counting_sort(list_input, int_max_value):
        '''
            @Description: Counting sort (계수 정렬)

            @Arguments Example
                # 0~10 사이의 정수라 가정
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''
        list_result = [0] * (int_max_value + 1)
        responce = []
        for int_value in list_input:
            list_result[int_value] += 1

        for int_index in range(int_max_value + 1):
            for _ in range(list_result[int_index]):
                responce.append(int_index)
        return responce


    if __name__ == "__main__":
        list_fn_counting_sort_param = [1, 9, 1, 2, 7, 3, 2, 8, 6, 1, 10, 10, 5, 6, 5, 9]
        print(fn_counting_sort(list_fn_counting_sort_param, 10))


'알고리즘 > 정렬' 카테고리의 다른 글

6. 힙 정렬 (Heap sort)  (0) 2020.01.27
5. 병합 정렬(Merge sort)  (0) 2020.01.26
4. 퀵 정렬 (Quick sort)  (0) 2020.01.26
3. 삽입 정렬 (Insertion sort)  (0) 2020.01.24
2. 버블정렬 (Bubble sort)  (0) 2020.01.24

사전 조건

- 배열이 완전 이진 트리 구조여야 한다.
    (완전 이진 트리 - Complete binary tree : 
     각각의 노드가 최대 2개 씩의 자식 노드를 가진 이진 트리 구조에서 
     root 노드의 왼쪽부터 자식 노드를 차례로 삽입하는 트리 구조를 말한다.)

종류

- 최대 힙 (부모 노드가 자식 노드보다 큰 힙)
- 최소 힙 (부모 노드가 자식 노드보자 작은 힙)

용어

- leaf 노드 : 자식 노드가 없는 노드들
- 힙 생성 알고리즘 (heapify) : 부모 노드와 자식 노드들 중에서 값이 가장 큰 값을 부모 노드로 변경 해주는 작업
- 상향식 : 아래 노드에서 위로 올라가는 작업
- 하향식 : 위에 노드부터 아래로 내려가는 작업
  (상향식과 하양식은 편한대로 구성한다. 저자는 상향식으로 구성했다.)

동작 방식

- 10개의 값이 있다고 가정하면 heapify작업을 하는 list의 index 값의 순서는 아래와 같다.
    index :  [자식노드 : 왼쪽 값] [부모노드] [자식노드 오른쪽 값]
    index :  9 4 
    index :  7 3 8
    index :  5 2 6
    index :  3 1 4
    index :  1 0 2
- 상단에 index 값 중에서 가장 큰 값을 가운데 부모 노드에 저장한다.
- 해당 작업을 전체 노드 수의 1/2 만큼만 진행한다.(leaf 노드를 제외하고 진행하기 때문)
- 작업이 끝나면 첫번째 값이 가장 큰 값이 되므로 가장 마지막 값과 자리를 바꾼다.
- 위 작업을 list의 작업 범위를 줄여가며 진행한다.
    0 ~9 작업 후 0 의 값을 9에 넣기
    0 ~8 작업 후 0 의 값을 8에 넣기
    ex) 배열 값 예시
        [7, 4, 5, 8, 9, 3, 2, 1, 6, 10]
        [6, 7, 5, 8, 4, 3, 2, 1, 9, 10]
        [1, 6, 5, 7, 4, 3, 2, 8, 9, 10]
        [2, 1, 5, 6, 4, 3, 7, 8, 9, 10]
        [3, 2, 5, 1, 4, 6, 7, 8, 9, 10]
        [2, 4, 3, 1, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

장점

- 퀵 정렬보다 안정적으로O(NlogN)을 보장한다.
- 메모리 상으로는 병합정렬 보다 효율적이다.

시간 복잡도

O(NlogN)
    - 힙 생성 알고리즘(heapify)작업에 걸리는 시간 복잡도는 완전 이진 트리 구조이기 때문에 로그2에 N 이다.
    - (1/2)n개의 정점에 대해서 진행하기 때문에 (1/2)n* 로그2에 N이다. 따라서 사실상 O(n)가까운 속도가 된다.
    - 그러나 공식적인 알고리즙의 시간 복잡도는 [힙 생성 알고리즘을 만드는데 걸리는 시간 logN] * [전체 데이터의 갯수 N]
    - 따라서 O(NlogN)이 된다.

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 27
    @ Update : 2020. 01. 27
    @ Description : Heap sort (힙 정렬)
    '''


    def fn_swapping(list_target, int_index_a, int_index_b):
        '''
            @Description: List index swapping

            @Arguments Example
                list_target = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
                int_index_a = 0
                int_index_b = 2
        '''
        value_tmp = list_target[int_index_a]
        list_target[int_index_a] = list_target[int_index_b]
        list_target[int_index_b] = value_tmp
        return list_target


    def fn_heap_sort(list_input):
        '''
            @Description: Heap sort (힙 정렬)

            @Arguments Example
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''

        int_len_list_input = len(list_input)
        for int_main_index in reversed(range(2, int_len_list_input + 1)):
            int_range = int_main_index//2
            if int_main_index%2 == 0:
                if list_input[int_range*2 - 1] > list_input[int_range - 1]:
                    list_input = fn_swapping(list_input, int_range*2 - 1, int_range - 1)
                int_range -= 1
            for int_index in reversed(range(1, int_range + 1)):
                if list_input[int_index*2 - 1] > list_input[(int_index*2)]:
                    if list_input[int_index*2 - 1] > list_input[int_index - 1]:
                        list_input = fn_swapping(list_input, int_index*2 - 1, int_index - 1)
                else:
                    if list_input[int_index*2] > list_input[int_index - 1]:
                        list_input = fn_swapping(list_input, int_index*2, int_index - 1)
                print("   index : ", int_index*2 - 1, int_index - 1, int_index*2)
            list_input = fn_swapping(list_input, 0, int_main_index - 1)
        return list_input


    if __name__ == "__main__":
        list_fn_heap_sort_param = [1, 9, 5, 4, 7, 3, 2, 8, 6, 10]
        print(fn_heap_sort(list_fn_heap_sort_param))

'알고리즘 > 정렬' 카테고리의 다른 글

7.계수 정렬 (Counting sort)  (0) 2020.01.28
5. 병합 정렬(Merge sort)  (0) 2020.01.26
4. 퀵 정렬 (Quick sort)  (0) 2020.01.26
3. 삽입 정렬 (Insertion sort)  (0) 2020.01.24
2. 버블정렬 (Bubble sort)  (0) 2020.01.24

동작 방식

- 반씩 쪼개서 합쳐 나가는 형태로 정렬을 한다.
- 모두 쪼개서 한개의 요소로 구성된 그룹으로 만든다.
- 그런다음 두개를 비교 할때 작은것을 앞으로 넣어 두개씩 그룹을 만든다.
- 그런다음 두그룹에서 맨앞에 있는 값중에 작은 값을 먼저 넣으면서 4개짜리 그룹을 만든다.
- 해당 작업을 반복을 하면 데이터의 갯수(N) 전체 반복작업 횟수 log8 = 3으로 NlogN을 보장한다.

장점

- O(NlogN)을 보장한다.

단점

 - 기존 데이터를 추가로 담을 메모리 공간이 필요해서 메모리 활용에 비효율 적이다.

시간 복잡도

O(NlogN)
    - 8개의 데이터가 있다 가정하면 데이터의 갯수(N) 전체 반복작업 횟수 log 2에 8 = 3으로 NlogN을 보장한다.

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 26
    @ Update : 2020. 01. 26
    @ Description : Merge sort (병합 정렬)
                    - 전역 변수로 사용 하면 메모리 사용 측면에서 효율 적이지만 그렇게 하지 않았다.
    '''

    def fn_merge_sort(list_input):
        '''
            @Description: Merge sort (병합 정렬)

            @Arguments Example
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''
        int_len_list_input = len(list_input)
        list_init = []
        int_merge_group_index_count = 1

        while int_len_list_input > int_merge_group_index_count:
            int_end_index = 0
            while int_end_index < int_len_list_input:
                int_index_b = int_end_index + int_merge_group_index_count*1
                int_index_c = int_index_b + int_merge_group_index_count*1
                list_init += fn_merge_list(list_input[int_end_index:int_index_b], list_input[int_index_b:int_index_c])
                int_end_index = int_index_c
            list_input = list_init
            list_init = []
            int_merge_group_index_count *= 2
        return list_input


    def fn_merge_list(list_a, list_b):
        '''
            @Description: Merge list

            @Arguments Example
                list_a = [1, 3]
                list_b = [2, 4]
        '''
        int_len_a = len(list_a)
        int_len_b = len(list_b)
        int_index_a = 0
        int_index_b = 0
        responce = []
        while int_index_a < int_len_a or int_index_b < int_len_b != 0:
            if int_index_b == int_len_b or (int_index_a < int_len_a and list_a[int_index_a] <= list_b[int_index_b]):
                responce += [list_a[int_index_a]]
                int_index_a += 1
            else:
                responce += [list_b[int_index_b]]
                int_index_b += 1
        print("fn_merge_list : " + str(responce))
        return responce


    if __name__ == "__main__":
        list_fn_merge_sort_param = [10, 1, 5, 8, 4, 3, 2, 9, 6, 7]
        print(fn_merge_sort(list_fn_merge_sort_param))

'알고리즘 > 정렬' 카테고리의 다른 글

7.계수 정렬 (Counting sort)  (0) 2020.01.28
6. 힙 정렬 (Heap sort)  (0) 2020.01.27
4. 퀵 정렬 (Quick sort)  (0) 2020.01.26
3. 삽입 정렬 (Insertion sort)  (0) 2020.01.24
2. 버블정렬 (Bubble sort)  (0) 2020.01.24

동작 방식

 - 맨 처음 값 기준으로 왼쪽에서 오른쪽으로 큰게 있는지 확인
 - 그런다음 오른쪽에서 왼쪽으로는 기준값보다 작은값이 있는지 확인
 - 그런다음 그 두 값의 자리를 바꾼다.
 - 그러다 작은값의 index 보다 큰 값의 index 값이 더 크게 되었을때
 - 기준 값과 작은 값을 자리를 바꾼다.
 - 그러면 기준값은 재자리를 찾았다.
 - 그런다음 기준값을 기준으로 왼쪽과 오른쪽 배열에 대해 위 작업을 반복 수행한다.

특징

평균적으로 속도가 가장 빨라라이브러리 등 많은 곳에서 쓰인다.

장점

- O(N×N) 정렬보다 압도적으로 빠르다.

단점

 - 최악의 경우에는 O(N×N)의 속도를 낸다 (ex > 배열이 이미 정렬이 되어 있는경우)
    분할 정복의 장점을 사용하지 못하기 때문.

시간 복잡도

O(NlogN)
    - 추론 1 : 원소가 10개의 배열 1개를 O(N*N) 작업을 한다고 가정 == 100
    - 추론 2 : 원소가 5개의 배열 2개를 O(N*N) 작업을 한다고 가정 == 50
    - 해당 원리를 '분할정복'이라 한다.
    - 따라서 기준값을 기준으로 반씩 쪼개기 때문에 logN  x 원소의 수 N
    - 결론 : 시간 복잡도는 NlogN

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 25
    @ Update : 2020. 01. 25
    @ Description : Quick sort (퀵 정렬)
    '''

    def fn_swapping(list_target, int_index_a, int_index_b):
        '''
            @Description: List index swapping

            @Arguments Example
                list_target = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
                int_index_a = 0
                int_index_b = 2
        '''
        value_tmp = list_target[int_index_a]
        list_target[int_index_a] = list_target[int_index_b]
        list_target[int_index_b] = value_tmp
        return list_target


    def fn_quick_sort(list_input):
        '''
            @Description: quick sort (퀵 정렬)

            @Arguments Example
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''
        int_len_list_input = len(list_input)
        value_standard = list_input[0]
        print("start : " + str(list_input))
        for _ in range(int_len_list_input):
            if int_len_list_input > 1:
                int_left_index = 0
                int_right_index = 0
                for int_index in range(1, int_len_list_input):
                    if value_standard < list_input[int_index]:
                        int_left_index = int_index
                        break
                for int_index in range(1, int_len_list_input):
                    if value_standard > list_input[int_len_list_input - int_index]:
                        int_right_index = int_len_list_input - int_index
                        break
                if int_left_index > int_right_index or int_left_index == 0:
                    list_input = fn_swapping(list_input, 0, int_right_index)
                    list_left_responce = []
                    list_right_responce = []

                    if int_right_index > 0:
                        list_left_responce = fn_quick_sort(list_input[0:int_right_index])

                    if len(list_input[int_right_index + 1:]) > 0:
                        list_right_responce = fn_quick_sort(list_input[int_right_index +1:])

                    if len(list_left_responce + list_right_responce) > 0:
                        list_input = list_left_responce + [value_standard] + list_right_responce
                    break
                else:
                    list_input = fn_swapping(list_input, int_right_index, int_left_index)
            else:
                return list_input
        return list_input


    if __name__ == "__main__":
        list_fn_quick_sort_param = [10, 1, 5, 8, 4, 3, 2, 9, 6, 7]
        print(fn_quick_sort(list_fn_quick_sort_param))

'알고리즘 > 정렬' 카테고리의 다른 글

6. 힙 정렬 (Heap sort)  (0) 2020.01.27
5. 병합 정렬(Merge sort)  (0) 2020.01.26
3. 삽입 정렬 (Insertion sort)  (0) 2020.01.24
2. 버블정렬 (Bubble sort)  (0) 2020.01.24
1. 선택정렬(Selection sort)  (0) 2020.01.24

동작 방식

배열에서 앞에 값들 중 적절한 곳에 위치 시킨다.
    ex> [10, 5, 1] 의 배열이라 가정
        - 10은 맨 앞의 값이라 건너 뛴다.
        - 5는 앞의 값 10의 앞 또는 뒤 두 곳중 한 곳에 갈 수 있다.
        - 해당 값은 10보다 작으므로 10을 뒤로 밀고 [5, 10, 1]로 만든다.
        - 1은 맨 앞, 5와 10 사이 그리고 10 뒤에 세 곳중 한 곳에 갈 수있다.
        - 1은 가장 작으니 맨앞으로 가고 나머지를 뒤로 밀어준다. [1, 5, 10]

특징

동작 하는 기준 값의 앞에 있는 배열은 이미 정렬되어 있다는 가정하에 작업한다.

장점

- 특징 때문에 일반적으로 버블정렬이나 선택 정렬 보다 빠르다.
- 배열이 거의 정렬이 되어 있는경우 O(NlongN)의 복잡도를 가지는 배열(퀵, 병합, 힙)보다도 빠르다.

시간 복잡도

O(N*N)
    - 추론 1 : 10 + 9 + 8 ... +1 번 비교 작업
    - 추론 2 : N(N+1)/2
    - 추론 3 : '/2'는 N이 엄청 큰 수라고 가정 했을 경우 의미 없는 값으로 처리한다
    - 결론 : 시간 복잡도는 N*N

동작 순서 예시

[10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
[5, 10, 1, 8, 4, 3, 2, 9, 6, 7]
[1, 5, 10, 8, 4, 3, 2, 9, 6, 7]
[1, 5, 8, 10, 4, 3, 2, 9, 6, 7]
[1, 4, 5, 8, 10, 3, 2, 9, 6, 7]
[1, 3, 4, 5, 8, 10, 2, 9, 6, 7]
[1, 2, 3, 4, 5, 8, 10, 9, 6, 7]
[1, 2, 3, 4, 5, 8, 9, 10, 6, 7]
[1, 2, 3, 4, 5, 6, 8, 9, 10, 7]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 24
    @ Update : 2020. 01. 24
    @ Description : Insertion sort (삽입 정렬)
    '''

    def fn_swapping(list_target, int_index_a, int_index_b):
        '''
            @Description: List index swapping

            @Arguments Example
                list_target = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
                int_index_a = 0
                int_index_b = 2
        '''
        value_tmp = list_target[int_index_a]
        list_target[int_index_a] = list_target[int_index_b]
        list_target[int_index_b] = value_tmp
        return list_target

    def fn_insertion_sort(list_input):
        '''
            @Description: Insertion sort (삽입 정렬)

            @Arguments Example
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''

        int_len_list_input = len(list_input)
        for int_list_input_index in range(int_len_list_input):
            for int_index in range(0, int_list_input_index):
                if list_input[int_index] > list_input[int_list_input_index]:
                    value_tmp = list_input[int_list_input_index]
                    for int_move_index in range(int_list_input_index - int_index):
                        list_input = fn_swapping(list_input, int_list_input_index - int_move_index, int_list_input_index - int_move_index - 1)
                    list_input[int_index] = value_tmp
                    break
            print(list_input)

    if __name__ == "__main__":
        list_fn_insertion_sort_param = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        fn_insertion_sort(list_fn_insertion_sort_param)

'알고리즘 > 정렬' 카테고리의 다른 글

6. 힙 정렬 (Heap sort)  (0) 2020.01.27
5. 병합 정렬(Merge sort)  (0) 2020.01.26
4. 퀵 정렬 (Quick sort)  (0) 2020.01.26
2. 버블정렬 (Bubble sort)  (0) 2020.01.24
1. 선택정렬(Selection sort)  (0) 2020.01.24

동작 방식

 - 배열의 바로 다음값과 비교해서 큰값을 뒤로 자리를 바꿔준다
 - 해당 작업을 처음부터 끝까지 한번 진행하면 맨뒤에 가장 큰 값이 간다.
 - 그러므로 그다음은 위 작업을 마지막 배열 전까지 작업을 한다.
 - 해당 작업을 반복하면 정렬이 이루어 진다.

단점

 - 선택정렬보다 효율이 엄청 떨어짐 (자리를 바꾸는 작업이 훨씬 더 많기 때문.)

시간 복잡도

O(N*N)
    - 추론 1 : 10 + 9 + 8 ... +1 번 비교 작업
    - 추론 2 : N(N+1)/2
    - 추론 3 : '/2'는 N이 엄청 큰 수라고 가정 했을 경우 의미 없는 값으로 처리한다
    - 결론 : 시간 복잡도는 N*N

동작 순서 예시

[5, 1, 8, 4, 3, 2, 9, 6, 7, 10]
[1, 5, 4, 3, 2, 8, 6, 7, 9, 10]
[1, 4, 3, 2, 5, 6, 7, 8, 9, 10]
[1, 3, 2, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 24
    @ Update : 2020. 01. 24
    @ Description : Bubble sort (버블 정렬)
    '''

    def fn_swapping(list_target, int_index_a, int_index_b):
        '''
            @Description: List index swapping

            @Arguments Example
                list_target = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
                int_index_a = 0
                int_index_b = 2
        '''
        value_tmp = list_target[int_index_a]
        list_target[int_index_a] = list_target[int_index_b]
        list_target[int_index_b] = value_tmp
        return list_target

    def fn_bubble_sort(list_input):
        '''
            @Description: Bubble sort (버블 정렬)

            @Arguments Example
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''

        int_len_list_input = len(list_input)
        for int_list_input_index in range(int_len_list_input):
            for int_index in range(0, int_len_list_input - int_list_input_index -1):
                if list_input[int_index + 1] < list_input[int_index]:
                    list_input = fn_swapping(list_input, int_index, int_index + 1)
            print(list_input)

    if __name__ == "__main__":
        list_fn_bubble_sort_param = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        fn_bubble_sort(list_fn_bubble_sort_param)

'알고리즘 > 정렬' 카테고리의 다른 글

6. 힙 정렬 (Heap sort)  (0) 2020.01.27
5. 병합 정렬(Merge sort)  (0) 2020.01.26
4. 퀵 정렬 (Quick sort)  (0) 2020.01.26
3. 삽입 정렬 (Insertion sort)  (0) 2020.01.24
1. 선택정렬(Selection sort)  (0) 2020.01.24

+ Recent posts