문제: 하나의 수조 길이가 n으로 가장 작은 k개의 원소를 구하고 작은 것에서 큰 출력으로
다음 세 가지 해결 방법을 생각해 보십시오.
1. 가장 간단한 것은 수조에 순서를 정하고 앞의 k개 원소를 출력한다. OK.
장점은 간단명료하다는 것이다.단점은 많은 추가 작업을 했다는 것이다. k개 원소 뒤에 있는 것은 필요없다.
2. 위보다 나은 것은 한 무더기를 사용하거나 나무를 정렬하는 것이다.우선 그룹의 앞 k개 요소를 이 더미에 삽입하거나 두 갈래 트리를 정렬합니다.그리고 뒤에 있는 모든 원소에 대해
a. 이 요소를 더미에 삽입하거나 두 갈래 나무에 정렬하기;
b. 이 무더기나 정렬 두 갈래 나무에서 가장 큰 원소를 제거합니다.
무더기로 이루어진다면 무더기 정렬을 참고할 수 있다.정렬 트리를 사용하면 기존의 TreeSet: (주: 여기 요구 사항이 있습니다. 입력 그룹의 요소가 모두 같지 않습니다)
private static void solveSet(int[] data, int count) {
TreeSet set = new TreeSet();
for (int i=0; i
무더기와 정렬 트리의 삽입 삭제가 비교적 빠르기 때문에, 그 성능은 전체 수조 정렬보다 틀림없이 강할 것이다.
내 테스트 결과, 1억 개의 데이터로 시간 대비
ms used for treeset 660 ms used for sort 2153
오케이, 그럼 더 빠른 방법은 없을까?예전의 그룹에서 k번째 작은 요소를 선택하는 호어 알고리즘을 생각해 냈다.
또한 유사하다. 수조에서 k번째 작은 요소를 선택하면 전체 수조를 정렬할 필요가 없고 빠른 정렬과 유사한 과정이다.
a) 우선 그룹에서 하나의 수 m 선택
b) 수조의 원소를 정리하고 m보다 작은 것은 왼쪽에 놓고 m보다 큰 것은 오른쪽에 놓는다.작은 부분과 큰 부분의 순서는 상관없고 m보다 작은 것만 요구하면 된다.
c) 정리한 후에 m의 위치가 마침 k라면 k의 작은 것은 m이다. 직접 m로 돌아가 끝낸다.
d) 그렇지 않으면 m의 위치 > k, 찾을 요소가 왼쪽에 있음을 나타냅니다.왼쪽 부분을 똑같이 처리한다.
만약 m의 위치
먼저 k 번째 작은 코드를 찾으면 다음과 같습니다.
class Hoare {
public static void main(String[] argu) {
int testSize = 100;
int[] t1 = new int[100];
Random r = new Random();
for (int i=0; i
이 알고리즘을 사용하여 k번째 작은 것을 찾습니다.찾은 후에 앞의 원소가 모두 k보다 작다는 것을 보증할 수 있기 때문에 앞의 원소에 대해 다시 순서를 정해야 한다.이번에 정렬할 원소가 매우 적기 때문에 속도가 빠르다.
private static void solveHoare(int[] data, int count) {
int k = Hoare.select(data, count, 0, data.length - 1);
int[] temp = Arrays.copyOfRange(data, 0, count);
Arrays.sort(temp);
System.out.println("Final data " + Arrays.toString(temp));
}
비교해 보면 찾으려는 원소의 개수가 수조의 길이보다 훨씬 적은 경우 이런 알고리즘이 가장 빠르다.
수조의 길이가 1억일 때 가장 작은 100개 원소를 열거하고 시간은 다음과 같다.
ms used for treeset 9315 ms used for sort 2373 ms used for selectk 201
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
2-1, 첫 파이썬 프로그램「Win」키+「R」키를 누르고, 이름란에 「cmd」를 입력하고, 「OK」버튼을 누르면, 코멘트 프롬프트가 열립니다. C :>보고 싶은 곳에 파이썬을 입력하면 파이썬 인터프리터가 시작됩니다. ">>>"라는 프롬프트가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.