정렬 알고리즘의 안정성은 무엇이며 왜 중요합니까?


292

정렬 알고리즘에서 안정성이 중요하지 않은 이유는 무엇입니까?


2
병렬화 목적으로? 예 : 병합 정렬은 안정적이며 병렬화가 가능하며 빠른 정렬도 가능합니다.
DarthVader

13
클래식 이것은 QuickSort는 불안정
콘스탄틴 Spirin

9
안정적인 종류의 너 한테 -IBM (Insertion, Bubble, Merge)
roottraveller

나와 같은 개념을 오해 할 수있는 사람들을위한 참고 사항 : 동일한 요소의 순서가 유지됩니다. 의미 : 안정적인 정렬의 요소가 동일한 것으로 간주되면 이전 순서를 따릅니다. 그것은 아니다 이전 주문의 요소가 정렬 오는 안정에 다음 동일한 것으로 간주하는 경우, 그들은 이전의 명령을 따를 것입니다 : 내가 생각하는 데 사용되는 것. 후자의 이해는 많은 경우에 의미가 있습니다.
Rick

답변:


371

동일한 키를 가진 두 객체가 정렬 될 입력 배열에 나타나는 것과 동일한 순서로 정렬 된 출력으로 나타나는 경우 정렬 알고리즘이 안정적 이라고합니다 . 일부 정렬 알고리즘은 삽입 정렬, 병합 정렬, 버블 정렬 등과 ​​같이 본질적으로 안정적입니다. 일부 정렬 알고리즘은 힙 정렬, 빠른 정렬 등이 아닙니다.

배경 : "안정한"정렬 알고리즘은 동일한 정렬 키를 가진 항목을 순서대로 유지합니다. 5 글자 단어 목록이 있다고 가정합니다.

peach
straw
apple
spork

각 단어의 첫 글자로 목록을 정렬하면 안정적인 정렬이 생성됩니다.

apple
peach
straw
spork

에서 불안정 정렬 알고리즘, straw또는 spork교환 할 수 있지만, (이후, 안정한 하나, 그들은 동일한 상대 위치를 유지 straw하기 전에 나타나는 spork입력에, 또한 이전에 나타나는 spork출력에서).

이 알고리즘을 사용하여 단어 목록을 정렬 할 수 있습니다. 5 열, 4, 3, 2, 1을 기준으로 안정적인 정렬입니다. 결국 올바르게 정렬됩니다. 스스로를 확신 시키십시오. (그런데 그 알고리즘을 기수 정렬이라고합니다)

이제 귀하의 질문에 대답하기 위해 이름과 성 목록이 있다고 가정하십시오. "성을 기준으로 정렬 한 다음 먼저 정렬"하라는 메시지가 표시됩니다. 먼저 이름으로 (안정 또는 불안정) 정렬 한 다음 성으로 안정 정렬 할 수 있습니다. 이러한 정렬 후 목록은 주로 성으로 정렬됩니다. 그러나 성이 동일한 경우 이름이 정렬됩니다.

같은 방식으로 불안정한 정렬을 쌓을 수 없습니다.


그렇다면 사과 복숭아 스포츠 짚의 올바른 정렬 순서로 단어를 만들기 위해 어떤 종류의 호출이 필요합니까? 안정적인 정렬은 우리에게 사과 복숭아 밀짚을 주었다. 그러나 세인트는 sp (알파벳으로 정확) 이후에 있어야한다. 따라서 궁극적 인 올바른 정렬은 사과 복숭아 스포츠 밀짚이어야한다
user1416486

2
@ user1416486 : 첫 글자 만 정렬합니다. 그 가정,로 strawspork동등한 비교합니다. 안정적인 정렬은 입력 순서를 유지하지만 불안정한 정렬은 보장하지 않습니다. "정확한"은 응용 프로그램에 따라 다릅니다. 대부분의 프로그래밍 언어에서 정렬 기능을 사용하면 사용자 정의 주문 기능을 제공 할 수 있습니다. 사용자의 기능이 다른 항목을 동일하게 취급하는 경우 (예 : 동일한 이름, 다른 성) 원래 주문이 유지되는지 확인하는 데 도움이됩니다. 실제 예제는 OCaml의 배열 정렬 함수 를 참조하십시오 .
Joey Adams

3
.. 같은 정렬 키를 이해하지 못 합니까? 여기서 키가 무엇을 의미합니까? .. 동일한 정렬 키
saplingPro

2
@saplingPro : "정렬 키"라는 말은 항목을 정렬하는 것을 의미합니다. 따라서 첫 글자로 정렬 한 다음 각 항목에 대해 "정렬 키"가 첫 글자입니다.
Joey Adams

12
예- 비행 목적지 및 출발 시간에 대한 정보가있는 각 항목의 목록이 있다고 가정하십시오. 먼저 시간을 기준으로 목록을 정렬합니다. 그런 다음 대상을 기준으로 정렬합니다. 두 번째 정렬이 안정 되면 이제 모든 항공편이 동일한 목적지로 묶이고 출발 시간이 늘어납니다. 안정적이지 않으면 시간 순서가 증가하지 않을 것입니다.
roottraveller

55

안정적인 정렬 알고리즘 은 입력에 표시되는 것과 동일한 순서로 동일한 요소를 정렬하는 알고리즘 이며, 불안정한 정렬 은 경우를 만족시키지 않을 수 있습니다 . - 알고리즘 강사 인 Didem Gozupek에게 알고리즘에 대한 통찰력을 제공해 주셔서 감사합니다 .

안정적인 정렬 알고리즘 :

  • 삽입 정렬
  • 정렬 병합
  • 버블 정렬
  • 팀 정렬
  • 계산 정렬
  • 블록 정렬
  • 쿼드 소트
  • 라이브러리 정렬
  • 칵테일 셰이커 정렬
  • 그놈 정렬
  • 홀짝 정렬

불안정한 정렬 알고리즘 :

  • 힙 정렬
  • 선택 정렬
  • 쉘 정렬
  • 빠른 정렬
  • 소개 (Quicksort에 따라)
  • 트리 정렬
  • 사이클 정렬
  • 스무스 소트
  • 토너먼트 정렬 (Hesapsort에 따라)

여기에 이미지 설명을 입력하십시오


2
귀하의 가치가 동일하지 않습니다. 9,7과 9,8을 비교하지만 안정성 검사에 따라 9,7 또는 9,8과 같은 동일한 값이 필요합니다. 그리고 안정적인 알고리즘에서 동일한 값을 동일한 순서로 정렬해야합니다.
erhun

1
아니요, 안정성을 확인하려면 값이 같아야합니다. 나는 두 개의 9,7을 사용하고 노드 A와 노드 B에서 이름을 지정한다고 가정합니다. 모든 정렬 작업 순서가 A, B와 같으면 (동일하지 않고) 정렬 알고리즘이 안정적이라는 것을 이해하십시오 (병합 정렬). 여러 번 정렬 할 때 A, B 순서가 변경되면 (1. 정렬 A, B, B, A 다시 A, B 등) 정렬 알고리즘이 불안정 함 (빠른 정렬과 같은) @snr
erhun

@snr [9, 6]은 입력 배열에 없습니다. 마지막 배열에서 [9, 8]을 의미한다고 생각합니다.
Usman

4
@erhun 나는 그가 첫 번째 숫자 (쉼표 앞의 숫자)로만 정렬하고 두 번째 숫자를 참조로 사용하여 첫 번째 9가 두 번째 9와 다르다는 것을 알 수 있습니다.
Tiago

20

정렬 안정성은 동일한 키를 가진 레코드가 정렬 전후에 상대 순서를 유지함을 의미합니다.

따라서 해결하려는 문제가 상대 순서를 유지해야하는 경우에만 안정성이 중요합니다.

안정성이 필요하지 않은 경우 heapsort 또는 quicksort와 같은 라이브러리에서 빠른 메모리 확보 알고리즘을 사용하고 잊어 버릴 수 있습니다.

안정성이 필요하면 더 복잡합니다. 안정적인 알고리즘은 불안정한 알고리즘보다 큰 CPU 및 / 또는 메모리 사용량을 갖습니다. 따라서 큰 데이터 세트가있는 경우 CPU 또는 메모리의 비팅 중 하나를 선택해야합니다. CPU와 메모리 모두에 제한이 있으면 문제가있는 것입니다. 좋은 절충 안정 안정적인 알고리즘은 이진 트리 정렬입니다. 위키 백과 문서는 STL과 기반으로 불쌍하기 쉬운 C ++ 구현이있다.

각 레코드의 마지막 위치 키로 원래 레코드 번호를 추가하여 불안정한 알고리즘을 안정적인 알고리즘으로 만들 수 있습니다.


1
병합 정렬과 같은 안정적인 알고리즘은 Quicksort와 동일한 O (NlogN) 복잡성을 갖습니다. 그러나 노력에 대한 지속적인 승수는 더 큽니다.
Jonathan Leffler

예, 병합 정렬의 메모리 사용량은 O (N)이며 퀵 정렬에서는 O (log N)입니다. 내가 Quicksort를 언급 한 이유는 qsort ()가 C 표준 라이브러리 루틴이기 때문에 확실하게 사용할 수 있기 때문입니다.
Bob Murphy

1
최고의 전체 답변 IMHO. 다른 것들에서 언급 된 멀티 키 기술은 흥미롭지 만 과대 평가되어있다. 적용하는 것은 간단하지만 명백한 대안보다 훨씬 느린 경향이 있습니다 (멀티 키 비교로 하나의 정렬을 사용하거나 첫 번째 키로 정렬 한 다음 중복으로 하위 목록을 식별하고 정렬). 안정적인 정렬이 예측 가능한 결과를 생성한다는 사실은 일부 앱에서 중요 할 수 있습니다. 특히 목록 B에 추가 항목이 있다는 점을 제외하고 동일한 두 개의 입력 목록 A, B가있는 경우 안정적인 정렬에 대한 출력은 B에 동일한 추가 항목이 있다는 점을 제외하고 동일합니다. 마지막 pgph의 경우 +1
greggo

16

그것은 당신이하는 일에 달려 있습니다.

이름과 성 필드가있는 사람들 레코드가 있다고 가정하십시오. 먼저 이름별로 목록을 정렬합니다. 그런 다음 성으로 안정적인 알고리즘으로 목록을 정렬하면 이름과 성으로 목록이 정렬됩니다.


4
나는 당신이 "성과 성"을 의미한다고 생각합니다. 성은 일반적으로 성입니다.
베이컨 비트

14

안정성이 중요한 몇 가지 이유가 있습니다. 하나는 두 레코드를 서로 바꿔서 교체 할 필요가없는 경우 메모리 업데이트가 발생할 수 있고 페이지가 더티로 표시되어 디스크 (또는 다른 느린 매체)로 다시 작성되어야한다는 것입니다.


레코드 교환은 안정성과 어떤 관련이 있습니까?
user1683793

4

동일한 키를 가진 두 개의 객체가 정렬되지 않은 입력에서 정렬되지 않은 입력으로 나타나는 경우 정렬 알고리즘은 안정적이라고 말합니다. 일부 정렬 알고리즘은 삽입 정렬, 병합 정렬, 버블 정렬 등과 ​​같이 본질적으로 안정적입니다. 일부 정렬 알고리즘은 힙 정렬, 빠른 정렬 등이 아닙니다.

그러나, 안정적이지 않은 임의의 주어진 분류 알고리즘은 안정적으로 변형 될 수있다. 정렬 알고리즘을 안정적으로 만드는 정렬 방법이있을 수 있지만 일반적으로 본질적으로 안정적이지 않은 비교 기반 정렬 알고리즘은 키 비교 작업을 변경하여 안정적으로 수정하여 두 키의 비교가 위치를 동일한 키를 가진 객체의 계수.

참고 문헌 : http://www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability


3

나는 이것에 대한 많은 답변이 있습니다 알고 있지만, 나에게, 이 답변 에 의해 로버트 하비 훨씬 더 명확하게 요약 :

안정적인 정렬은 [불안정한] 알고리즘이 두 개 이상의 항목을 구분하지 않는 입력 세트의 원래 순서를 유지하는 정렬입니다.

출처


1

정렬하려는 항목이 숫자라고 가정하고 해당 값만 식별하고 구별하는 경우 (예 : 동일한 값을 가진 요소가 우연한 경우) 정렬의 안정성 문제는 의미가 없습니다.

그러나 정렬에서 우선 순위가 동일한 개체는 서로 다를 수 있으며 때로는 상대 순서가 의미있는 정보입니다. 이 경우 불안정한 정렬로 인해 문제가 발생합니다.

예를 들어, 게임에서 레벨 [L]로 미로를 청소하는 모든 플레이어의 시간 비용 [T]가 포함 된 데이터 목록이 있습니다. 미로 청소 속도에 따라 플레이어 순위를 정해야한다고 가정 해 봅시다. 그러나 추가 규칙이 적용됩니다. 미로를 더 높은 레벨로 청소하는 플레이어는 시간이 얼마나 오래 걸리더라도 항상 더 높은 순위를 갖습니다.

물론 규칙을 따르는 알고리즘을 사용하여 쌍으로 된 값 [T, L]을 실수 [R]에 매핑 한 다음 모든 플레이어의 순위를 [R] 값으로 지정할 수 있습니다.

그러나 안정적인 정렬이 가능한 경우 전체 목록을 [T] (빠른 플레이어)와 [L]로 정렬하면됩니다. 이 경우 플레이어가 청소 한 미로 수준으로 그룹화 한 후에는 시간 순서에 따른 상대 순서가 변경되지 않습니다.

추신 : 물론 두 번 정렬하는 접근법은 특정 문제에 대한 최선의 해결책은 아니지만 포스터 문제를 설명하는 것으로 충분합니다.


0

안정적인 정렬은 항상 동일한 입력에서 동일한 솔루션 (순열)을 반환합니다.

예를 들어 [2,1,2]는 순열 [2,1,3]과 같이 안정적인 정렬을 사용하여 정렬됩니다 (먼저 인덱스 2, 인덱스 1, 인덱스 3, 정렬 된 출력의 인덱스 3). 결과는 항상 같은 방식으로 섞입니다. 다른 비 안정적이지만 여전히 올바른 순열은 [2,3,1]입니다.

빠른 정렬은 안정적인 정렬이 아니며 동일한 요소 간의 순열 차이는 피킹 피킹 알고리즘에 따라 다릅니다. 일부 구현은 임의로 선택되어 동일한 알고리즘을 사용하여 동일한 입력에서 다른 순열을 빠르게 정렬 할 수 있습니다.

결정적인 안정적인 정렬 알고리즘이 필요합니다.


2
그것은 안정성이 의미하는 것이 아닙니다. 참조 en.wikipedia.org/wiki/Sorting_algorithm#Stability
루이스 올리베이라

비 정렬 정렬이 동일한 구현 중에서도 다른 솔루션을 출력 할 수있는 것보다 비 안정적인 정렬보다 마지막 문장을 수정해야합니다.
Luka Rahne

1
왜 -1입니까? 누군가가 여기서 무엇이 잘못되었는지 지적 할 수 있습니까? 이것은 안정적으로 정렬되는 것이 아니라 안정적인 정렬이 갖는 속성입니다.
Luka Rahne

정렬이 결정적인지 여부는 정렬이 안정적인지 여부를 결정하지 않습니다. 다른 타이 브레이킹 동작을 정의하여 (예를 들어 키가 아닌 부분을 분류함으로써) 비 안정적인 결정적 정렬 알고리즘을 작성할 수 있습니다. 안정적인 정렬은 구체적으로 관계가 정렬 될 때 요소의 미리 정렬 된 상대적 순서가 유지됨을 의미합니다. 안정적인 정렬의 출력 예 : 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)]있지만 이것은 안정적인 정렬이 아닙니다.
cowbert

@cowbert 그것은 모든 안정적인 종류가 가지고있는 좋은 속성에 대해 더 많은 진술입니다. 그것은 마녀 안정적인 정렬 알고리즘 또는 구현이 사용 되더라도, 동일한 결과가있을 때마다 있습니다. 서로 다른 비 안정적인 정렬 구현 중에서 이러한 속성을 유지하기가 더 어렵습니다.
Luka Rahne

0

안정적인 정렬을 원하는 이유의 더 많은 예. 데이터베이스가 일반적인 예입니다. 성, 구매 날짜, 품목 번호, 가격을 포함하는 것보다 거래 데이터베이스의 경우를 생각해보십시오. 데이터베이스가 일반적으로 날짜 | 시간으로 정렬되어 있다고 가정하십시오. 그리고, 안정된 소트는 원래 순서를 유지하기 때문에 질의에 의해 데이터베이스의 소트 된 사본을 성명에 의해 조회하도록하는데, 문의는 성만 포함하더라도 각성에 대한 거래는 데이터 순서대로되어 있습니다.

비슷한 예는 한 번에 3 개의 열로 정렬을 제한하는 클래식 Excel입니다. 6 개의 열을 정렬하기 위해 가장 중요하지 않은 3 개의 열로 정렬 한 다음 가장 중요한 3 개의 열로 정렬합니다.

안정적인 기수 정렬의 전형적인 예는 기본 10 숫자 열의 필드를 기준으로 정렬하는 데 사용되는 카드 분류기입니다. 카드는 최하위 자릿수에서 최상위 자릿수로 정렬됩니다. 각 패스에서 카드 한 벌을 읽고 해당 열의 숫자에 따라 10 개의 다른 빈으로 분리합니다. 그런 다음 10 개의 빈 카드를 순서대로 입력 호퍼에 다시 넣습니다 ( "0"카드, "9"카드 마지막). 그런 다음 모든 열이 정렬 될 때까지 다음 열에서 다른 패스를 수행합니다. 실제 카드 분류기는 카드에 12 개의 영역이 있고 열이 비어있을 수 있으며 잘못 판독 된 용지함이 있기 때문에 10 개 이상의 용지함이 있습니다. 문자를 정렬하려면 열당 2 패스, 숫자에 대한 1 패스, 12 11 존의 2 패스가 필요합니다.

이후 (1937)에는 필드를 비교하여 두 개의 카드 덱을 병합 할 수있는 카드 조합 (병합) 시스템이있었습니다. 입력은 이미 분류 된 2 개의 카드 덱, 마스터 덱과 업데이트 덱이었습니다. collator는 두 개의 데크를 새로운 교합 상자와 보관함으로 병합했습니다.이 보관함은 선택적으로 마스터 복제에 사용 되었기 때문에 새 마스터 저장소는 복제시 업데이트 카드 만 갖습니다. 이것은 아마도 원래 (아래쪽) 병합 정렬의 아이디어에 대한 기초 일 것입니다.

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