정렬 알고리즘 - 자바 구현 (하) 빠 른 정렬
여기 서 하나의 알고리즘 만 말 하고 빠 른 정렬 을 하 는 이 유 는 정렬 효율 이 같은 O (nlogn) 의 몇 가지 정렬 방법 중에서 효율 이 가장 높 기 때문에 자주 사용 되 기 때문이다.게다가 빠 른 정렬 사상 인 분 치 법 도 실 용적 이어서 각 공장 의 면접 에서 가장 많은 질문 을 받 았 다.
1. 기본 사상:
빠 른 정렬 은 일반적으로 재 귀적 으로 이 루어 진다.그 사고방식 은 다음 과 같다. (1) 적당 한 값 을 선정 하여 '주 원' 또는 '중추' (pivot) 라 고 부른다.(2) 이 값 을 바탕 으로 배열 을 두 개의 부분 집합 으로 나 누고 작은 것 은 왼쪽 에 있 으 며 큰 것 은 오른쪽 에 있다.(3) 두 개의 키 배열 에 대해 상기 과정 을 반복 하고 각 배열 에 하나의 요소 만 있 을 때 까지 한다.(4) 정렬 완료.
빠 른 정렬 이 빠 른 이 유 는 주 원 이 한 번 만 이동 하면 최종 위치 에 놓 이기 때문이다.가장 좋 은 상황: 매번 선택 한 주 원 이 마침 그 가 있어 야 할 위치 에 있 을 때 (왼쪽 은 그 보다 작고 오른쪽 은 그 보다 크다) 이것 은 빠 른 정렬 알고리즘 의 가장 좋 은 상황 이 고 알고리즘 시간 이 복잡 할 때
O(nlogn)
.최 악의 경우: 구역 을 나 눌 때마다 하위 서열 의 길이 가 1 개 씩 n - 1 로 나타 나 는데 그것 은 정말 최 악이 다.이것 은 반드시 우리 의 표현 식 을 다음 과 같이 만 들 것 이다. T(n) = O(n) + T(1) + T(n-1) = O(n) + T(n-1)
이것 은 정렬 을 삽입 하고 정렬 을 선택 하 는 관계 식 과 똑 같 기 때문에 우리 의 최 악의 상황 은 O(n²)
이다.2 코드 구현:
세부 적 인 실현 이 좋 고 나 쁨 은 빠 른 정렬 의 효율 에 큰 영향 을 주 므 로 몇 가지 주의해 야 할 점 이 있다.
2.1 주 원 을 어떻게 선택 합 니까?
(1) 고정 기준 수가 배열 이 질서 가 있 으 면 위의 방식 으로 는 매우 좋 지 않다. 매번 구분 할 때마다 정렬 대기 서열 의 길 이 를 1 로 줄 일 수 밖 에 없 기 때문이다.시간 복잡 도 O (n)²)。따라서 첫 번 째 원 소 를 기준 으로 사용 하 는 것 은 매우 나쁘다.
(2) 랜 덤 기준 수 는 상대 적 으로 안전 한 전략 입 니 다. 기준 수의 위치 가 랜 덤 이기 때문에 발생 하 는 분할 도 항상 저질 분할 이 나타 나 지 않 습 니 다. 그러나
random
함수 자체 가 소모 되 기 때문에 이 방법 도 좋 지 않 습 니 다.(3) 세 개 수의 중위 수 를 선택 하여 무 작위 기준 수 방법 으로 선택 하 는 방식 은 분할 하기 어 려 운 확률 을 줄 였 지만 최 악의 경우
O(n²)
이 어색 한 분 위 기 를 완화 시 키 기 위해 '3 수 취 중' 이라는 기준 수 선택 방식 을 도입 했다.// pivot,
private static int Median3(int arr[], int left, int right) {
int center = (left + right) / 2;
if (arr[left] > arr[center]) {
swap(arr, left, center);
}
if (arr[left] > arr[right]) {
swap(arr, left, right);
}
if (arr[center] > arr[right]) {
swap(arr, center, right);
}
// right-1 , right center,
swap(arr, center, right-1);
return arr[right - 1];
}
private static void swap(int arr[], int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
여기 서 우 리 는 중위 수 를 선택 할 뿐만 아니 라 배열 도 일정한 수정 을 했 습 니 다. pivot 와 배열 의 right - 1 위 를 교환 합 니 다. right 위치의 값 은 앞의 비 교 를 통 해 pivot 보다 클 것 입 니 다. 더 이상 비교 하지 않 아 도 됩 니 다. 우 리 는 정렬 해 야 할 것 은 left + 1 에서 right - 2 위치 까지 의 요소 정렬 입 니 다. 이것 은 효율 을 크게 절약 합 니 다.
2.2 부분 집합 구분 을 어떻게 하 는 지:
부분 집합 구분 을 최적화 하 는 데 다음 과 같은 몇 가지 방법 이 있다. (1) 양쪽 에서 중간 으로 옮 겨 다 니 는 양 방향 구분 방식:
private static void quickSortStadard(int[] array, int N) {
quickSort(arr, 0, N - 1);
}
private static void quickSort(int arr[], int left, int right) {
if(right-left>3) {
int pivot = Median3(arr, left, right);
int i = left;
int j = right - 1;
for (;;) {
// , arr[i]>arr[pivot]
while (arr[++i] < pivot) {
}
// , arr[j] pivot) {
}
if (i < j) {
swap(arr, i, j);
} else {
break;
}
}
// right-1 i
swap(arr, i, right - 1);
//
quickSort(arr, left, i - 1);
//
quickSort(arr, i + 1, right);
}else {
insertSort(arr, arr.length);
}
}
public static void insertSort(int[] array, int N) {
int i, j, temp = 0;
for (i = 1; i < array.length; i++) {//
temp = array[i];//
for (j = i; j > 0 && array[j - 1] > temp; j--) {// ,
array[j] = array[j - 1]; // ,
}
array[j] = temp;//
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.