데이터 구조 | 빠 른 정렬, 2 번 빠 른 정렬, 3 번 빠 른 정렬
5021 단어 데이터 구조
1. 빠 른 정렬
1. 개념
빠 른 정렬 은 분 치 된 사상 으로 데 이 터 를 정렬 합 니 다.
2. 시간 복잡 도
빠 른 정렬 구간 을 나 눌 때 O (logN) 이 고 매번 시간 복잡 도 를 O (N) 로 정렬 해 야 합 니 다.
그래서 빠 른 배열 의 시간 복잡 도 는 O (NLogN) 이 고 이 는 기준 치 에 대해 구간 을 대충 등분 할 수 있 는 상황 이다.
데이터 가 질서 가 있 으 면 매번 나 눌 때마다 한 쪽 에 데이터 가 하나 도 없고 다른 한 쪽 은 데이터 가 있 을 수 있 습 니 다. 그러면 거품 정렬 과 같 습 니 다. 시간 복잡 도 는 O (N ^ 2) 입 니 다.
위 에서 말 한 바 와 같이:
가장 좋 은 시간 복잡 도: O (NLogN)
최 악의 시간 복잡 도: O (N ^ 2)
3. 어 울 리 는 장면
빠 른 정렬 은 데이터 가 무질서 한 상황 에 적합 합 니 다. 데이터 가 질서 가 있 을 때 시간 복잡 도 는 O (N ^ 2) 일 가능성 이 높 고 빠 른 배열 의 장점 을 나타 내지 않 습 니 다.
4. 최적화
세 가지 방법 으로 중 법 을 취하 거나 랜 덤 으로 기준 치 를 선택 할 수 있다.
5. 실현
빠 른 배열 의 parion 함수 에 대해 세 가지 실현 방법 이 있 습 니 다.
//
int Partion(int array[], int left, int right)
{
int cur = left;
int prev = cur - 1;
while (cur < right)
{
if (array[cur] <= array[right] && ++prev != cur)
{
std::swap(array[cur], array[prev]);
}
cur++;
}
std::swap(array[++prev], array[right]);
return prev;
}
void QuickSort(int array[], int left, int right)
{
if (array == nullptr)
{
return;
}
if (left < right)
{
int index = Partion(array, left, right);
QuickSort(array, left, index - 1);
QuickSort(array, index + 1, right);
}
}
기타 실현 방법 및 최적화 코드:https://github.com/YKitty/LinuxDir/blob/master/DS/Sort/Sort.c
2. 2 번 고속 열차
1. 나타 난 원인
빠 른 배열 에 있어 데이터 요소 가 너무 많 고 요소 의 크기 가 매우 가깝다 면 이때 좌우 로 나 눌 때 한 쪽 은 모두 데이터 이 고 다른 한 쪽 은 데이터 가 없 으 면 효율 이 떨 어 지고 시간 복잡 도 는 O (N ^ 2) 로 변 한다.
예 를 들 어 템 플 릿 으로 정렬 과 빠 른 정렬 시간 을 테스트 하고 1000000 개의 배열 을 설정 합 니 다. 배열 요 소 는 0 - 10 사이 에 무 작위 로 값 을 추출 합 니 다. 그러면 병합 을 사용 하려 면 0.290727 s 가 필요 하고 빠 른 배열 은 171.151 s 가 필요 합 니 다. 맞습니다. 잘못 보지 않 았 습 니 다.빠 른 정렬 이 가장 좋 을 때 는 o (nlgn) 이 고 이 때 는 o (n ^ 2) 의 단계 로 퇴화 되 었 습 니 다.왜 이래?
위 에서 내 가 쓴 빠 른 배열 에 대해 기준 치 보다 작은 데 이 터 를 모두 왼쪽 에 놓 고 큰 것 을 오른쪽 에 놓 으 면 문제 가 생 길 수 있다.조건 이 같 든 작 든 배열 에서 중복 요소 가 매우 많 을 때 기준 치 와 같은 요소 가 너무 많 으 면 배열 은 극도로 불 균형 한 두 부분 으로 나 뉜 다. 기준 치 와 같은 부분 은 항상 배열 의 한 쪽 에 집중 되 기 때문이다.
이때 2 번 빠 른 배열 을 사용 하면 최적화 되 어 효율 이 떨 어 지 는 것 을 막 을 수 있다.
2 번 빠 른 속도 로 해결 하 는 문제:
기준 치 와 같은 요 소 를 모두 배열 의 한쪽 에 집중 시 키 지 않 습 니 다.
2. 사상
3. 어 울 리 는 장면
배열 에서 중복 되 는 요소 가 너무 많 을 때 빠 른 배열 을 사용 할 수 없고 2 번 빠 른 배열 을 사용 하면 된다.
4. 실현
이 루어 질 때 는 파 티 온 함수 만 바 꾸 면 됩 니 다.
int Partion_Two(int array[], int left, int right)
{
int l = left;
int r = right - 1;
while (1)
{
while (l <= r && array[l] < array[right])
{
l++;
}
while (l <= r && array[r] > array[right])
{
r--;
}
if (l > r)
{
break;
}
std::swap(array[r], array[l]);
}
std::swap(array[l], array[right]);
return r;
}
주의: 왼쪽 에서 작 지 않 은 것 을 찾 고 오른쪽 에서 크 지 않 은 것 을 찾 은 다음 에 판단 교환 을 합 니 다.
3. 3 번 고속도로
1. 생각
배열 을 세 부분 으로 나 누 어 기준 치 보다 적 고 기준 치 와 같은 기준 치 의
다음 세 개의 아래 표 시 를 기록 합 니 다:
lt: 기준 치 보다 작은 마지막 아래 표
gt: 기준 치 보다 큰 첫 번 째 아래 표
index: 옮 겨 다 니 는 아래 표 시 를 표시 합 니 다.
index 기준 치보다 작 음: 교환 index 와 l + 1, l + +
index 기준 치 이상: 교환 index 와 lt - 1, gt --
index 는 기준 값 과 같 습 니 다: index +
종료 조건: index = lt
마지막 교환 기준 치:
swap(arr[lt], arr[right])
계속 진행 되 는 구간:
[left,lt-1]
[gt, right]
2. 실현
void QuickSort_Three(int array[], int left, int right)
{
if (array == nullptr)
{
return;
}
if (right <= left)
{
return;
}
int lt = left - 1;
int gt = right;
int index = left;
int key = array[right];
while (index < gt)
{
if (array[index] < key)
{
std::swap(array[index], array[lt + 1]);
lt++;
index++;
}
else if (array[index] > key)
{
std::swap(array[index], array[gt - 1]);
gt--;
}
else
{
index++;
}
}
std::swap(array[index], array[right]);
QuickSort_Three(array, left, lt );
QuickSort_Three(array, gt, right);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.