삽입 정렬과 선택 정렬


109

삽입 정렬과 선택 정렬의 차이점을 이해하려고합니다.

둘 다 두 가지 구성 요소 인 정렬되지 않은 목록과 정렬 된 목록이있는 것 같습니다. 둘 다 정렬되지 않은 목록에서 하나의 요소를 가져와 적절한 위치에 정렬 된 목록에 넣는 것 같습니다. 삽입 정렬은 단순히 올바른 지점을 찾아서 삽입하는 동안 선택 정렬이 한 번에 하나씩 교체하여이 작업을 수행한다고 말하는 사이트 / 책을 보았습니다. 그러나 다른 기사에서 삽입 정렬도 바뀐다 고 말하는 것을 보았습니다. 결과적으로 나는 혼란 스럽습니다. 표준 소스가 있습니까?


8
선택 정렬을 위한 위키피디아는 삽입 정렬을 위한 것과 마찬가지로 의사 코드와 예쁜 그림과 함께 제공됩니다 .
G. Bach

6
@ G.Bach-감사합니다 ... 두 페이지를 여러 번 읽었지만 차이점을 이해하지 못합니다.
eb80 2013-04-04

3
Computerphile에 따르면 그들은 동일합니다 : youtube.com/watch?v=pcJHkWwjNl4
Tristan Forward

답변:


185

선택 정렬 :

목록이 주어지면 현재 요소를 가져 와서 현재 요소의 오른쪽에있는 가장 작은 요소와 교환합니다. 선택 정렬

삽입 정렬 :

목록이 주어지면 현재 요소를 목록의 적절한 위치에 삽입하고 삽입 할 때마다 목록을 조정합니다. 카드 게임에서 카드를 배열하는 것과 비슷합니다. 삽입 정렬

선택 정렬의 시간 복잡도는 항상있는 n(n - 1)/2반면 삽입 정렬은 최악의 경우 복잡도이므로 시간 복잡도가 더 좋습니다 n(n - 1)/2. 일반적으로 그보다 적거나 같은 비교가 필요 n(n - 1)/2합니다.

출처 : http://cheetahonfire.blogspot.com/2009/05/selection-sort-vs-insertion-sort.html


2
@ Nikolay- 이것은 내가 이미 읽은 cheetahonfire.blogspot.com/2009/05/… 에서 복사되었습니다 . 상충되는 기사를 읽었을 때 더 많은 콘서트가 있습니까?
eb80 2013

5
주요 차이점은 선택 단계입니다. 삽입 정렬의 적절한 위치에 현재 삽입 첫번째로 선택 정렬 선택 최소 하나를 스왑
니콜라이 코스 톱

6
@ eb80 어떤 자료를 읽고 있는지 잘 모르겠지만 예제가 이보다 더 구체적 일 수있는 방법을 모르겠습니다.
G. Bach

23
그러나 스왑 수는 어떻습니까? 선택은 항상 n (n-1) / 2 개의 비교를 수행하지만 최악의 경우 n-1 스왑 만 수행합니다. 최악의 경우 삽입은 n (n-1) / 2 개의 비교와 n (n-1) / 2 개의 스왑을 수행합니다.
Jason Goemaat

2
@Adorn 둘 다 분할 및 정복 알고리즘이 아닙니다.
Asky McAskface 2017

63

삽입 정렬과 선택 정렬에는 모두 외부 루프 (모든 인덱스에 대해)와 내부 루프 (인덱스 하위 집합에 대해)가 있습니다. 내부 루프의 각 패스는 정렬되지 않은 요소가 부족해질 때까지 정렬되지 않은 영역을 희생하여 정렬 된 영역을 하나의 요소로 확장합니다.

차이점은 내부 루프가 수행하는 작업입니다.

  • 선택 정렬에서 내부 루프는 정렬되지 않은 요소 위에 있습니다. 각 패스는 하나의 요소를 선택하고 최종 위치 (정렬 된 영역의 현재 끝)로 이동합니다.

  • 삽입 정렬에서 내부 루프의 각 패스는 정렬 된 요소를 반복 합니다. 정렬 된 요소는 루프가 다음 정렬되지 않은 요소를 삽입 할 올바른 위치를 찾을 때까지 대체됩니다.

따라서 선택 정렬에서 정렬 된 요소는 출력 순서로 발견되고 발견되면 그대로 유지됩니다. 반대로, 삽입 정렬에서 정렬되지 않은 요소는 입력 순서대로 소비 될 때까지 그대로 유지되고 정렬 된 영역의 요소는 계속 이동합니다.

스와핑에 관한 한 : 선택 정렬은 내부 루프의 패스 당 하나의 스왑을 수행합니다. 삽입 정렬은 일반적으로 내부 루프 temp 이전 과 같이 삽입 할 요소를 저장하여 내부 루프가 정렬 된 요소를 하나씩 위로 이동 한 다음 temp나중에 삽입 지점으로 복사 할 공간을 남겨 둡니다 .


23

SELECTION SORT
특정 / 무작위 방식으로 쓰여진 숫자 배열이 있다고 가정하고 오름차순으로 배열한다고 가정합시다. 따라서 한 번에 하나의 숫자를 가져 와서 가장 작은 숫자로 대체하십시오. 목록에서 사용할 수 있습니다. 이 단계를 수행하면 궁극적으로 원하는 결과를 얻을 수 있습니다.

여기에 이미지 설명 입력



INSERTION SORT
비슷한 가정을 염두에두고 있지만 유일한 차이점은 이번에는 한 번에 하나의 숫자를 선택하고 미리 정렬 된 부분에 삽입하므로 비교가 줄어들어 더 효율적이라는 것입니다.

여기에 이미지 설명 입력


Youtube 에서 mycodeschool 을 확인하십시오 . 그러나이 답변은 YouTube의 두 가지 알고리즘 비디오에서 설명한 내용을 칭찬합니다.
JaydeepW

21

연결 목록 정렬에 대한 설명을 배열 정렬에 대한 설명과 비교하기 때문에 혼란이있을 수 있습니다 . 그러나 나는 당신이 당신의 출처를 인용하지 않았기 때문에 확신 할 수 없습니다.

정렬 알고리즘을 이해하는 가장 쉬운 방법은 종종 알고리즘에 대한 자세한 설명을 얻는 것입니다 ( "이 종류는 스왑을 사용합니다. 어딘가에 있습니다. 나는 어디를 말하는 것이 아닙니다"와 같은 모호하지 않음). 간단한 정렬 알고리즘의 경우), 알고리즘을 직접 실행하십시오.

선택 정렬 : 정렬되지 않은 데이터를 검색하여 남은 가장 작은 요소를 찾은 다음 정렬 된 데이터 바로 다음 위치로 교체합니다. 끝날 때까지 반복하십시오. 목록을 정렬하는 경우 가장 작은 요소를 위치로 바꿀 필요가 없습니다. 대신 목록 노드를 이전 위치에서 제거하고 새 위치에 삽입 할 수 있습니다.

삽입 정렬 : 정렬 된 데이터 바로 뒤에있는 요소를 가져와 정렬 된 데이터를 스캔하여 배치 할 위치를 찾아 거기에 배치합니다. 끝날 때까지 반복하십시오.

삽입 정렬 "스캔"단계에서 스왑 사용할 있지만 반드시 그럴 필요는 없으며 다음과 같은 데이터 유형의 배열을 정렬하지 않는 한 가장 효율적인 방법이 아닙니다. (a) 이동할 수없고 복사 또는 스왑 만 가능합니다. (b) 스왑보다 복사하는 데 더 비쌉니다. 삽입 정렬을 사용 스왑을 수행하는 경우가 작동하는 방식은 동시에 장소를 검색한다는 것입니다 긴 요소로는보다 큰 전과를 들어, 반복적으로 직전 요소와 새로운 요소를 교환하여, 거기에 새로운 요소를 넣어 그것. 더 크지 않은 요소에 도달하면 올바른 위치를 찾은 다음 다음 새 요소로 이동합니다.


1
이것은 매우 도움이됩니다. 마지막 단락은 각 종류의 변형에서 비롯된 혼란에 빠졌습니다.
eb80 2013-04-04

1
연결된 목록에서 삽입 정렬을 사용하는 것이
인플레 이스

11

두 알고리즘의 논리는 매우 유사합니다. 둘 다 배열의 시작 부분에 부분적으로 정렬 된 하위 배열이 있습니다. 유일한 차이점은 정렬 된 배열에 넣을 다음 요소를 검색하는 방법입니다.

  • 삽입 정렬 : 올바른 위치에 다음 요소를 삽입 합니다.

  • 선택 정렬 : 가장 작은 요소를 선택 하여 현재 항목과 교환합니다.

또한 Insertion SortSelection Sort 와 달리 안정적 입니다.

나는 두 가지를 모두 파이썬으로 구현했으며 얼마나 유사한 지 주목할 가치가 있습니다.

def insertion(data):
    data_size = len(data)
    current = 1
    while current < data_size:
        for i in range(current):
            if data[current] < data[i]:
                temp = data[i]
                data[i] = data[current]
                data[current] = temp

        current += 1

    return data

약간만 변경하면 선택 정렬 알고리즘을 만들 수 있습니다.

def selection(data):
    data_size = len(data)
    current = 0
    while current < data_size:
        for i in range(current, data_size):
            if data[i] < data[current]:
                temp = data[i]
                data[i] = data[current]
                data[current] = temp

        current += 1

    return data

죄송합니다. 왜 (선택 정렬 알고리즘) 데이터 [i]가 작아 질 때마다 데이터 [i]가 데이터 [current]와 교환되는지 궁금합니다. 기본 / 원본 (?) 선택 정렬에서는 범위 (i, data_size) 중에서 최소값을 찾고 그 최소값으로 데이터 [i]를 교환합니다. 약간 다릅니다 ...
Tony Ma

4

간단히 말해서, 선택 정렬은 배열에서 가장 작은 값을 먼저 검색 한 다음 스왑을 수행하는 반면 삽입 정렬은 값을 가져 와서 그 뒤에있는 각 값과 비교한다고 생각합니다. 값이 더 작 으면 바뀝니다. 그런 다음 동일한 값을 다시 비교하고 뒤에있는 값보다 작 으면 다시 바꿉니다. 이해가 되길 바랍니다!


4

요컨대

선택 정렬 : 정렬 되지 않은 배열에서 첫 번째 요소를 선택하고 정렬되지 않은 나머지 요소와 비교합니다. 버블 정렬과 비슷하지만 작은 요소를 각각 교체하는 대신 가장 작은 요소 색인을 업데이트 한 상태로 유지하고 각 루프의 끝에서 교체합니다 .

삽입 정렬 : 정렬되지 않은 하위 배열에서 첫 번째 요소를 선택하여 정렬 된 하위 배열과 비교하고 발견 된 가장 작은 요소를 삽입하고 정렬 된 모든 요소를 ​​오른쪽에서 첫 번째 정렬되지 않은 요소로 이동 하는 선택 정렬과 반대 입니다.


3

나는 또 다른 시도를 할 것이다. 거의 정렬 된 배열의 운이 좋은 경우에 무슨 일이 일어나는지 생각 해보자.

정렬하는 동안 배열은 왼쪽-정렬 됨, 오른쪽-정렬되지 않음의 두 부분으로 간주 될 수 있습니다.

삽입 정렬-정렬되지 않은 첫 번째 요소를 선택하고 이미 정렬 된 부분 중에서 해당 위치를 찾습니다. 오른쪽에서 왼쪽으로 검색하기 때문에 비교중인 첫 번째 정렬 된 요소 (가장 큰 요소, 왼쪽 부분에서 가장 오른쪽)가 선택한 요소보다 작아서 다음 정렬되지 않은 요소를 즉시 계속할 수 있습니다.

선택 정렬-정렬되지 않은 첫 번째 요소를 선택하고 정렬되지 않은 전체 부품 중 가장 작은 요소를 찾고 원하는 경우이 두 요소를 교환합니다. 문제는 오른쪽 부분이 분류되지 않았기 때문에 선택한 것보다 더 작은 요소가 있는지 여부를 확신 할 수 없기 때문에 매번 모든 요소를 ​​생각해야한다는 것입니다.

Btw., 이것이 바로 heapsort 가 선택 정렬에서 개선 한 입니다. heap으로 인해 가장 작은 요소를 훨씬 더 빨리 찾을 수 있습니다.


3

선택 정렬 : 정렬 된 하위 목록 작성을 시작할 때 알고리즘은 정렬 된 하위 목록이 자체 요소뿐만 아니라 전체 배열, 즉 정렬 된 하위 목록과 정렬되지 않은 하위 목록 모두의 관점에서 항상 완전히 정렬되도록합니다. 따라서 정렬되지 않은 하위 목록에서 발견 된 가장 작은 새 요소는 정렬 된 하위 목록의 끝에 추가됩니다.

삽입 정렬 : 알고리즘은 배열을 다시 두 부분으로 나누지 만 여기서 요소는 두 번째 부분에서 선택되어 첫 번째 부분에 올바른 위치에 삽입됩니다. 물론 최종 패스에서 모든 요소가 올바른 정렬 위치에 있지만 첫 번째 부분이 전체 배열 측면에서 정렬된다는 보장은 없습니다.


3

두 알고리즘 모두 일반적으로 다음과 같이 작동합니다.

1 단계 : 정렬되지 않은 목록에서 다음 정렬되지 않은 요소를 가져온 다음

2 단계 : 정렬 된 목록의 올바른 위치에 배치합니다.

단계 중 하나는 하나의 알고리즘에 대해 더 쉽고 그 반대의 경우도 마찬가지입니다.

삽입 정렬 : 정렬 되지 않은 목록의 첫 번째 요소를 가져 와서 정렬 된 목록의 어딘가에 넣습니다 . 다음 요소 (정렬되지 않은 목록의 첫 번째 위치)를 가져올 위치를 알고 있지만, 배치 할 위치를 찾으려면 약간의 작업이 필요합니다 ( 어딘가 ). 1 단계는 간단합니다.

선택 정렬 : 우리는 요소 걸릴 어딘가에 다음, 정렬되지 않은 목록에서를 정렬 된 목록의 마지막 위치에 넣어. 다음 요소 (정렬되지 않은 목록의 첫 번째 위치가 아니라 어딘가에있을 가능성이 높음 )를 찾은 다음 정렬 된 목록의 끝에 바로 배치해야합니다. 2 단계는 쉽습니다.


2

삽입 정렬의 내부 루프는 이미 정렬 된 요소를 통과합니다 (선택 정렬과 반대). 이렇게하면 올바른 위치가 발견 될 때 내부 루프중단 할 수 있습니다 . 의미하는 것은:

  1. 내부 루프는 평균적인 경우 요소의 절반 만 통과합니다.
  2. 배열이 거의 정렬되면 내부 루프가 더 빨리 중단됩니다.
  3. 배열이 이미 정렬 된 경우 내부 루프가 즉시 중단되어이 경우 삽입 정렬의 복잡성이 선형이됩니다.

선택 정렬은 항상 모든 내부 루프 요소를 통과해야합니다. 이것이 삽입 정렬이 대부분 선택 정렬보다 선호되는 이유입니다. 그러나 다른 한편으로 선택 정렬은 요소 교체를 훨씬 적게 수행하므로 경우에 따라 더 중요 할 수 있습니다.


1

기본적으로 삽입 정렬은 한 번에 두 요소를 비교하여 작동하며 선택 정렬은 전체 배열에서 최소 요소를 선택하여 정렬합니다.

개념적으로 삽입 정렬은 전체 배열이 정렬 될 때까지 두 요소를 비교하여 하위 목록을 계속 정렬하는 반면 선택 정렬은 최소 요소를 선택하고 첫 번째 위치로 두 번째 최소 요소를 두 번째 위치로 바꾸는 식입니다.

삽입 정렬은 다음과 같이 표시 될 수 있습니다.

    for(i=1;i<n;i++)
        for(j=i;j>0;j--)
            if(arr[j]<arr[j-1])
                temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;

선택 정렬은 다음과 같이 표시 될 수 있습니다.

    for(i=0;i<n;i++)
        min=i;
        for(j=i+1;j<n;j++)
        if(arr[j]<arr[min])
        min=j;
        temp=arr[i];
        arr[i]=arr[min];
        arr[min]=temp;

1

이 두 가지 정렬 알고리즘의 선택은 사용되는 데이터 구조에 따라 결정됩니다.

배열을 사용할 때 선택 정렬을 사용하십시오 (왜 qsort를 사용할 수 있습니까?). 연결 목록을 사용하는 경우 삽입 정렬을 사용하십시오.

이 때문입니다:

  • 연결된 목록 순회는 배열보다 비쌉니다.
  • 연결된 목록 삽입은 배열보다 훨씬 저렴합니다.

삽입 정렬은 정렬 된 세그먼트의 중간에 새 값을 삽입합니다. 따라서 데이터를 "푸시 백"해야합니다. 그러나 연결 목록을 사용하는 경우 2 개의 포인터를 비틀어 전체 목록을 효과적으로 다시 밀어 넣은 것입니다. 배열에서 값을 되돌리려면 n-i 스왑을 수행해야하며 이는 매우 비쌀 수 있습니다.

선택 정렬은 항상 끝에 추가되므로 배열을 사용할 때이 문제가 발생하지 않습니다. 따라서 데이터를 "푸시 백"할 필요가 없습니다.


0

간단한 설명은 다음과 같습니다.

주어진 : 정렬되지 않은 배열 또는 숫자 목록입니다.

문제 설명 : 선택 정렬과 삽입 정렬의 차이점을 이해하기 위해 숫자 목록 / 배열을 오름차순으로 정렬합니다.

삽입 정렬 :더 쉽게 이해할 수 있도록 목록을 위에서 아래로 볼 수 있습니다. 첫 번째 요소를 초기 최소값으로 간주합니다. 이제 아이디어는 해당 목록 / 배열의 각 인덱스를 선형으로 탐색하여 인덱스에 초기 최소값보다 작은 값을 갖는 다른 요소가 있는지 알아내는 것입니다. 이러한 값을 찾으면 해당 인덱스의 값을 스왑합니다. 즉, 인덱스 1에서 15가 최소 초기 값이라고 가정하고 인덱스의 선형 순회 중에 더 작은 값 (예 : 인덱스 9에서 7)을 발견합니다. 이제 인덱스 9의이 값 7은 값이 15 인 인덱스 1로 교체됩니다. 이 순회는 현재 인덱스의 값과 나머지 인덱스의 비교를 계속하여 더 작은 값으로 스왑합니다. 이것은 목록 / 배열의 두 번째 마지막 색인까지 계속됩니다.

선택 정렬 :목록 / 배열의 첫 번째 인덱스 요소가 정렬되었다고 가정 해 보겠습니다. 이제 두 번째 인덱스의 요소에서 이전 인덱스와 비교하여 값이 더 작은 지 확인합니다. 순회는 정렬 및 정렬되지 않은 두 부분으로 시각화 될 수 있습니다. 하나는 정렬되지 않은 항목에서 목록 / 배열의 지정된 인덱스에 대해 정렬 된 항목으로 비교 검사를 시각화하는 것입니다. 인덱스 1에 값 19가 있고 인덱스 3에 값 10이 있다고 가정 해 봅시다. 정렬되지 않은 것에서 정렬 된 것, 즉 오른쪽에서 왼쪽으로 순회를 고려합니다. 따라서 인덱스 3에서 정렬해야한다고 가정 해 봅시다. 오른쪽에서 왼쪽으로 비교할 때 인덱스 1보다 값이 더 작다는 것을 알 수 있습니다. 일단 식별되면 인덱스 3의이 숫자 10을 19의 값을 갖는 인덱스 1의 자리에 배치합니다. 인덱스 1의 원래 값 19는 오른쪽으로 한 자리 이동합니다.

순회 방법의 개념을 이해하는 것에 관한 질문으로 보이는 코드를 추가하지 않았습니다.


0

삽입 정렬은 항목을 바꾸지 않습니다. temp 변수를 사용하더라도 temp var를 사용하는 포인트는 이전 인덱스의 값에 비해 인덱스의 값이 작다는 것을 발견했을 때 더 큰 값을 더 작은 값의 위치로 이동하는 것입니다. 덮어 쓰는 색인. 그런 다음 임시 변수를 사용하여 이전 색인에서 대체합니다. 예 : 10, 20, 30, 50, 40. 반복 1 : 10, 20, 30, 50, 50. [temp = 40] 반복 2 : 10,20, 30, 40 (임시 값), 50. 그래서, 우리는 일부 변수에서 원하는 위치에 값을 삽입하기 만하면됩니다.

그러나 선택 정렬을 고려할 때 먼저 더 낮은 값을 가진 인덱스를 찾고 그 값을 첫 번째 인덱스의 값으로 스왑하고 모든 인덱스가 정렬 될 때까지 반복적으로 스와핑을 계속합니다. 이것은 두 숫자의 전통적인 스와핑과 똑같습니다. 예 : 30, 20, 10, 40, 50. 반복 1 : 10, 20, 30, 40, 50. 여기서 temp var는 스와핑에만 사용됩니다.


0

삽입 정렬은 해당 선택 항목을 훨씬 더 많이 교체합니다. 다음은 예입니다.

여기에 이미지 설명 입력


0

둘 다 공통점은 배열의 정렬 된 부분과 정렬되지 않은 부분을 구별하기 위해 둘 다 파티션을 사용한다는 것입니다.

차이점은 선택 정렬을 사용하면 정렬 된 파티션에 요소를 추가 할 때 배열의 정렬 된 부분이 변경되지 않는다는 것입니다.

그 이유는 선택이 정렬되지 않은 세트의 최소값을 검색하고 정렬 된 세트의 마지막 요소 바로 뒤에 추가하기 때문에 정렬 된 세트가 1 씩 증가하기 때문입니다.

반면에 삽입은 배열의 정렬되지 않은 부분의 첫 번째 요소 인 다음 요소 만 고려합니다. 이 요소를 가져 와서 정렬 된 세트의 적절한 위치에 간단히 맞 춥니 다.

삽입 정렬은 일반적으로 최소값을 찾기 위해 작업을 낭비하기 때문에 부분적으로 만 정렬 된 배열에 대해 항상 더 나은 후보입니다.

결론:

선택 정렬 은 정렬되지 않은 섹션에서 최소 요소를 찾아 끝에 요소를 점진적으로 추가합니다.

삽입 정렬 은 정렬되지 않은 섹션에서 찾은 첫 번째 요소를 정렬 된 섹션의 모든 위치로 전파합니다.


0

선택 정렬과 삽입 정렬의 시간 복잡도는 동일하지만 n (n-1) / 2입니다. 평균 성능 삽입 정렬이 더 좋습니다. 무작위 30000 정수로 i5 CPU에서 테스트 한 결과 선택 정렬은 평균 1.5 초가 걸리고 삽입 정렬은 평균 0.6 초가 걸립니다.


StackOverflow에 오신 것을 환영하고 답변에 감사드립니다. 많은 사람들이 이미 시각적 삽화를 통해 멋진 답변을 제공했음을 알 수 있습니다. 예를 들어, 7 년 전 Nikolay Kostov는 삽입 정렬의 최악의 경우에만 시간 복잡성이 동일하다고 말했습니다. 그가 틀렸다고 생각되면 더 자세한 내용으로 답변을 확장 해 주시기 바랍니다.
Maxim Sagaydachny

-1

평신도 용어로 (그리고 아마도 문제에 대한 높은 수준의 이해를 얻는 가장 쉬운 방법)

버블 정렬은 줄을 서서 높이별로 정렬하려는 것과 유사합니다. 올바른 위치에 올 때까지 옆에있는 사람과 계속 전환합니다. 이는 왼쪽 (또는 구현에 따라 오른쪽)에서 끝까지 발생하며 모든 사람이 정렬 될 때까지 계속 전환합니다.

그러나 선택 정렬에서 수행하는 작업은 카드 한 장을 정렬하는 것과 유사합니다. 카드를보고 가장 작은 카드를 가져 와서 왼쪽 끝까지 놓는 식으로 계속합니다.


3
그는 선택과 삽입 정렬의 차이점에 대해 묻고 있습니다
XuDing

-1

선택-특정 항목 (가장 낮은 항목)을 선택하고 i (반복 없음) 번째 요소로 교체합니다. (즉, 첫 번째, 두 번째, 세 번째 .......) 따라서 정렬 된 목록을 한쪽에 만듭니다.

삽입-첫 번째와 두 번째 비교 세 번째와 두 번째 및 첫 번째 비교 네 번째와 세 번째, 두 번째 및 첫 번째 비교 ...

모든 정렬이 비교되는 링크

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.