정렬 알고리즘에서 안정성이 중요하지 않은 이유는 무엇입니까?
IBM (Insertion, Bubble, Merge)
정렬 알고리즘에서 안정성이 중요하지 않은 이유는 무엇입니까?
IBM (Insertion, Bubble, Merge)
답변:
동일한 키를 가진 두 객체가 정렬 될 입력 배열에 나타나는 것과 동일한 순서로 정렬 된 출력으로 나타나는 경우 정렬 알고리즘이 안정적 이라고합니다 . 일부 정렬 알고리즘은 삽입 정렬, 병합 정렬, 버블 정렬 등과 같이 본질적으로 안정적입니다. 일부 정렬 알고리즘은 힙 정렬, 빠른 정렬 등이 아닙니다.
배경 : "안정한"정렬 알고리즘은 동일한 정렬 키를 가진 항목을 순서대로 유지합니다. 5 글자 단어 목록이 있다고 가정합니다.
peach
straw
apple
spork
각 단어의 첫 글자로 목록을 정렬하면 안정적인 정렬이 생성됩니다.
apple
peach
straw
spork
에서 불안정 정렬 알고리즘, straw
또는 spork
교환 할 수 있지만, (이후, 안정한 하나, 그들은 동일한 상대 위치를 유지 straw
하기 전에 나타나는 spork
입력에, 또한 이전에 나타나는 spork
출력에서).
이 알고리즘을 사용하여 단어 목록을 정렬 할 수 있습니다. 5 열, 4, 3, 2, 1을 기준으로 안정적인 정렬입니다. 결국 올바르게 정렬됩니다. 스스로를 확신 시키십시오. (그런데 그 알고리즘을 기수 정렬이라고합니다)
이제 귀하의 질문에 대답하기 위해 이름과 성 목록이 있다고 가정하십시오. "성을 기준으로 정렬 한 다음 먼저 정렬"하라는 메시지가 표시됩니다. 먼저 이름으로 (안정 또는 불안정) 정렬 한 다음 성으로 안정 정렬 할 수 있습니다. 이러한 정렬 후 목록은 주로 성으로 정렬됩니다. 그러나 성이 동일한 경우 이름이 정렬됩니다.
같은 방식으로 불안정한 정렬을 쌓을 수 없습니다.
straw
와 spork
동등한 비교합니다. 안정적인 정렬은 입력 순서를 유지하지만 불안정한 정렬은 보장하지 않습니다. "정확한"은 응용 프로그램에 따라 다릅니다. 대부분의 프로그래밍 언어에서 정렬 기능을 사용하면 사용자 정의 주문 기능을 제공 할 수 있습니다. 사용자의 기능이 다른 항목을 동일하게 취급하는 경우 (예 : 동일한 이름, 다른 성) 원래 주문이 유지되는지 확인하는 데 도움이됩니다. 실제 예제는 OCaml의 배열 정렬 함수 를 참조하십시오 .
안정적인 정렬 알고리즘 은 입력에 표시되는 것과 동일한 순서로 동일한 요소를 정렬하는 알고리즘 이며, 불안정한 정렬 은 경우를 만족시키지 않을 수 있습니다 . - 알고리즘 강사 인 Didem Gozupek에게 알고리즘에 대한 통찰력을 제공해 주셔서 감사합니다 .
안정적인 정렬 알고리즘 :
불안정한 정렬 알고리즘 :
정렬 안정성은 동일한 키를 가진 레코드가 정렬 전후에 상대 순서를 유지함을 의미합니다.
따라서 해결하려는 문제가 상대 순서를 유지해야하는 경우에만 안정성이 중요합니다.
안정성이 필요하지 않은 경우 heapsort 또는 quicksort와 같은 라이브러리에서 빠른 메모리 확보 알고리즘을 사용하고 잊어 버릴 수 있습니다.
안정성이 필요하면 더 복잡합니다. 안정적인 알고리즘은 불안정한 알고리즘보다 큰 CPU 및 / 또는 메모리 사용량을 갖습니다. 따라서 큰 데이터 세트가있는 경우 CPU 또는 메모리의 비팅 중 하나를 선택해야합니다. CPU와 메모리 모두에 제한이 있으면 문제가있는 것입니다. 좋은 절충 안정 안정적인 알고리즘은 이진 트리 정렬입니다. 위키 백과 문서는 STL과 기반으로 불쌍하기 쉬운 C ++ 구현이있다.
각 레코드의 마지막 위치 키로 원래 레코드 번호를 추가하여 불안정한 알고리즘을 안정적인 알고리즘으로 만들 수 있습니다.
안정성이 중요한 몇 가지 이유가 있습니다. 하나는 두 레코드를 서로 바꿔서 교체 할 필요가없는 경우 메모리 업데이트가 발생할 수 있고 페이지가 더티로 표시되어 디스크 (또는 다른 느린 매체)로 다시 작성되어야한다는 것입니다.
동일한 키를 가진 두 개의 객체가 정렬되지 않은 입력에서 정렬되지 않은 입력으로 나타나는 경우 정렬 알고리즘은 안정적이라고 말합니다. 일부 정렬 알고리즘은 삽입 정렬, 병합 정렬, 버블 정렬 등과 같이 본질적으로 안정적입니다. 일부 정렬 알고리즘은 힙 정렬, 빠른 정렬 등이 아닙니다.
그러나, 안정적이지 않은 임의의 주어진 분류 알고리즘은 안정적으로 변형 될 수있다. 정렬 알고리즘을 안정적으로 만드는 정렬 방법이있을 수 있지만 일반적으로 본질적으로 안정적이지 않은 비교 기반 정렬 알고리즘은 키 비교 작업을 변경하여 안정적으로 수정하여 두 키의 비교가 위치를 동일한 키를 가진 객체의 계수.
참고 문헌 : http://www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability
정렬하려는 항목이 숫자라고 가정하고 해당 값만 식별하고 구별하는 경우 (예 : 동일한 값을 가진 요소가 우연한 경우) 정렬의 안정성 문제는 의미가 없습니다.
그러나 정렬에서 우선 순위가 동일한 개체는 서로 다를 수 있으며 때로는 상대 순서가 의미있는 정보입니다. 이 경우 불안정한 정렬로 인해 문제가 발생합니다.
예를 들어, 게임에서 레벨 [L]로 미로를 청소하는 모든 플레이어의 시간 비용 [T]가 포함 된 데이터 목록이 있습니다. 미로 청소 속도에 따라 플레이어 순위를 정해야한다고 가정 해 봅시다. 그러나 추가 규칙이 적용됩니다. 미로를 더 높은 레벨로 청소하는 플레이어는 시간이 얼마나 오래 걸리더라도 항상 더 높은 순위를 갖습니다.
물론 규칙을 따르는 알고리즘을 사용하여 쌍으로 된 값 [T, L]을 실수 [R]에 매핑 한 다음 모든 플레이어의 순위를 [R] 값으로 지정할 수 있습니다.
그러나 안정적인 정렬이 가능한 경우 전체 목록을 [T] (빠른 플레이어)와 [L]로 정렬하면됩니다. 이 경우 플레이어가 청소 한 미로 수준으로 그룹화 한 후에는 시간 순서에 따른 상대 순서가 변경되지 않습니다.
추신 : 물론 두 번 정렬하는 접근법은 특정 문제에 대한 최선의 해결책은 아니지만 포스터 문제를 설명하는 것으로 충분합니다.
안정적인 정렬은 항상 동일한 입력에서 동일한 솔루션 (순열)을 반환합니다.
예를 들어 [2,1,2]는 순열 [2,1,3]과 같이 안정적인 정렬을 사용하여 정렬됩니다 (먼저 인덱스 2, 인덱스 1, 인덱스 3, 정렬 된 출력의 인덱스 3). 결과는 항상 같은 방식으로 섞입니다. 다른 비 안정적이지만 여전히 올바른 순열은 [2,3,1]입니다.
빠른 정렬은 안정적인 정렬이 아니며 동일한 요소 간의 순열 차이는 피킹 피킹 알고리즘에 따라 다릅니다. 일부 구현은 임의로 선택되어 동일한 알고리즘을 사용하여 동일한 입력에서 다른 순열을 빠르게 정렬 할 수 있습니다.
결정적인 안정적인 정렬 알고리즘이 필요합니다.
sort([(5,3),(1,5),(3,3),(1,3)], x) => [(1,5),(1,3),(3,3),(5,3)]
. 항상 (결정 론적으로) 출력되는 결정 론적 정렬을 만들 수 [(1,3),(1,5),(3,3),(5,3)]
있지만 이것은 안정적인 정렬이 아닙니다.
안정적인 정렬을 원하는 이유의 더 많은 예. 데이터베이스가 일반적인 예입니다. 성, 구매 날짜, 품목 번호, 가격을 포함하는 것보다 거래 데이터베이스의 경우를 생각해보십시오. 데이터베이스가 일반적으로 날짜 | 시간으로 정렬되어 있다고 가정하십시오. 그리고, 안정된 소트는 원래 순서를 유지하기 때문에 질의에 의해 데이터베이스의 소트 된 사본을 성명에 의해 조회하도록하는데, 문의는 성만 포함하더라도 각성에 대한 거래는 데이터 순서대로되어 있습니다.
비슷한 예는 한 번에 3 개의 열로 정렬을 제한하는 클래식 Excel입니다. 6 개의 열을 정렬하기 위해 가장 중요하지 않은 3 개의 열로 정렬 한 다음 가장 중요한 3 개의 열로 정렬합니다.
안정적인 기수 정렬의 전형적인 예는 기본 10 숫자 열의 필드를 기준으로 정렬하는 데 사용되는 카드 분류기입니다. 카드는 최하위 자릿수에서 최상위 자릿수로 정렬됩니다. 각 패스에서 카드 한 벌을 읽고 해당 열의 숫자에 따라 10 개의 다른 빈으로 분리합니다. 그런 다음 10 개의 빈 카드를 순서대로 입력 호퍼에 다시 넣습니다 ( "0"카드, "9"카드 마지막). 그런 다음 모든 열이 정렬 될 때까지 다음 열에서 다른 패스를 수행합니다. 실제 카드 분류기는 카드에 12 개의 영역이 있고 열이 비어있을 수 있으며 잘못 판독 된 용지함이 있기 때문에 10 개 이상의 용지함이 있습니다. 문자를 정렬하려면 열당 2 패스, 숫자에 대한 1 패스, 12 11 존의 2 패스가 필요합니다.
이후 (1937)에는 필드를 비교하여 두 개의 카드 덱을 병합 할 수있는 카드 조합 (병합) 시스템이있었습니다. 입력은 이미 분류 된 2 개의 카드 덱, 마스터 덱과 업데이트 덱이었습니다. collator는 두 개의 데크를 새로운 교합 상자와 보관함으로 병합했습니다.이 보관함은 선택적으로 마스터 복제에 사용 되었기 때문에 새 마스터 저장소는 복제시 업데이트 카드 만 갖습니다. 이것은 아마도 원래 (아래쪽) 병합 정렬의 아이디어에 대한 기초 일 것입니다.