힙 정렬은 힙 데이터 구조를 사용하여 설계된 정렬 알고리즘을 나타냅니다. 스태킹은 대략적으로 이진 트리이며 스태킹의 특성을 충족시키는 구조입니다.
힙 정렬의 평균 시간 복잡성은 ο (nlogn)입니다.
알고리즘 단계 :
1. 힙 H [0..n-1]를 만듭니다.
2. 힙 헤드 (최대)와 힙 꼬리를 교체하십시오.
3. 힙 크기를 1 씩 줄이고 shift_down (0)을 호출하십시오. 목적은 새 배열의 상단 데이터를 해당 위치로 조정하는 것입니다.
4. 힙의 크기가 1이 될 때까지 2 단계를 반복합니다.
더미:
힙은 실제로 완전히 바이너리 트리이며, 잎이 아닌 노드의 비 잎 노드는 특성을 충족시킵니다. 키 [i] <= 키 [2i+1] && key [i] <= key [2i+2] 또는 키 [i]> = 키 [2i+1] && 키 [2i+2]의 키워드의 키워드보다 크지 않습니다. 힙은 큰 상단 힙과 작은 상단 힙으로 나뉩니다. 만족스러운 키 [i]> = key [2i+1] && key> = 키 [2i+2]를 큰 상단 힙이라고합니다. 만족스러운 키 [i] <= 키 [2i+1] && 키 [i] <= 키 [2i+2]를 작은 상단 힙이라고합니다. 위의 속성에서, 우리는 대형 상단 힙 상단의 키워드가 확실히 모든 키워드 중 가장 큰 키워드이며, 작은 상단 힙 상단의 키워드는 모든 키워드 중 가장 작은 것임을 알 수 있습니다.
힙 분류 아이디어 :
대형 상단 힙 (작은 상단 힙)의 상단에 기록 된 최대 키워드 (최소 키워드)의 기능을 사용하면 매번 장애에서 가장 큰 레코드 (최소 레코드)를 간단하게 선택할 수 있습니다. 기본 아이디어는 (큰 상단 힙)입니다. 1) 초기 키워드를 정렬 할 초기 키워드 (R1, R2… 2) 힙 상부 요소 R [1]을 마지막 요소 R [N]으로 교환 한 다음 새로운 무질서한 영역 (R1, R2,… RN-1) 및 새로운 순서 영역 (RN)을 얻고 R [1,2… N-1] <= R [N]; 3) 교환 후 새로운 힙 상단 R [1]가 힙의 특성을 위반할 수 있기 때문에, 현재 무질서한 영역 (R1, R2,… RN-1)을 새로운 힙으로 조정 한 다음 R1, R2… 정렬 된 영역의 요소 수가 N-1이되고 전체 분류 프로세스가 완료 될 때 까지이 프로세스를 반복하십시오. 작동 프로세스는 다음과 같습니다. 1) 힙을 초기화합니다 : r [1..n]을 힙으로 구성하십시오. 2) 현재 순서가없는 영역의 힙 상위 요소 R [1]을 간격으로 마지막 레코드로 교환 한 다음 새로운 숫자 영역을 새 힙으로 조정하십시오. 따라서 힙 분류의 경우 가장 중요한 두 가지 작업은 초기 힙을 구성하고 힙을 조정하는 것입니다. 실제로, 초기 힙을 구성하는 것은 실제로 힙을 조정하는 과정이지만 초기 힙을 구성하는 것은 모든 비 잎 노드를 조정하는 것입니다.
그림의 예
형성 어레이 A [] = {16,7,3,20,17,8}가 주어지면 힙은 정렬됩니다. 먼저 배열 요소를 기반으로 완전한 이진 트리를 만들고 얻습니다.
그런 다음 초기 힙을 구성한 다음 마지막 비 잎 노드에서 조정을 시작해야합니다. 조정 프로세스는 다음과 같습니다.
20과 16, 16을 교환 한 후 16은 힙의 특성을 충족시키지 못하므로 재조정해야합니다.
이것은 초기 힙을 제공합니다.
먼저 조정되면 큰 상단 더미가됩니다.
즉, 각 조정은 부모 노드, 왼쪽 자식 노드 및 오른쪽 하위 노드에서 가장 큰 조정을 부모 노드와 교환하기 위해 가장 큰 조정을 선택하는 것입니다 (교환 후에 교환 된 하위 노드는 하위 노드가 힙의 특성을 충족시키지 않도록 교환 할 수 있으므로 교환중인 자식 노드가 다시 조정되어야합니다). 초기 힙을 사용하면 정렬 할 수 있습니다.
현재 3은 파일의 상단에 위치하고 속성은 더미로 가득 차 있지 않습니다. 조정하고 계속 조정해야합니다.
이런 식으로 전체 간격은 이미 순서입니다. 위의 과정에서 힙 분류가 실제로 일종의 선택 분류, 트리 선택 분류임을 알 수 있습니다. 그러나 순서를 직접 선택하려면 R [1 ... N]에서 최대 레코드를 선택하려면 N-1 배를 비교 한 다음 R [1 ... N-2]에서 최대 레코드를 선택하고 N-2 배를 비교해야합니다. 실제로, 이러한 N-2 비교 중 다수는 이전 N-1 비교에서 수행되었으며 트리 선택 분류는 트리의 특성을 사용하여 이전 비교 결과 중 일부를 저장하므로 비교 횟수를 줄일 수 있습니다. N 키워드 시퀀스의 경우 최악의 경우 각 노드는 Log2 (N) 시간을 비교해야하므로 최악의 경우 복잡성이 Nlogn입니다. 힙 정렬은 불안정한 정렬이며 레코드가 적은 상태로 정렬하는 데 적합하지 않습니다. 위에서 설명한 많은 것들이 있습니다. 요컨대, 힙 분류의 기본 관행은 다음과 같습니다. 첫째, 원래 데이터를 사용하여 원래의 작은 힙을 원래의 불균형 영역으로 구축 한 다음마다 힙 상단 요소가 꺼져서 주문한 영역에 배치됩니다. 힙의 상단 요소가 꺼내므로 힙의 마지막 요소를 힙 상단에 넣으므로 힙의 특성이 파괴됩니다. 우리는 힙을 다시 조정하고 n 번 계속 조정해야한다면, 순서가없는 영역의 n 요소가 정렬 된 영역에 넣고 분류 프로세스가 완료됩니다.
(건물 스택은 아래에서 상단까지)
실제 응용 프로그램 :
실제로, 우리는 특정 조건에서 최대 또는 최소값을 얻기 위해 힙 분류를 수행합니다. 예를 들어 : 10 최대 값은 100 개의 숫자 중 하나를 찾아야합니다. 따라서 크기 10의 힙을 정의하고, 100의 작은 상단 힙 (힙 상단)에 100의 첫 10 개의 데이터를 빌드 한 다음 100 개의 데이터의 11 번째 데이터의 힙 상단과 비교합니다. 힙 상단이 현재 데이터보다 작 으면 힙 상단이 팝업 된 경우 현재 데이터를 힙 상단으로 누른 다음 데이터를 힙 상단에서 특정 위치로 이동하십시오.
암호:
public class test0 {static int [] arr; // heap array, 유효한 배열 public test0 (int m) {arr = new = new int [m];} 정적 int m = 0; static int size = 0; heap public void addtosmall (int v) {// int [] a = {16,4,5,9,1,11,12,13,14,15,2,3,6,8,111,222,333,555,66,67,54}; // 힙 크기는 10 // arr = new입니다 int [10]; if (size <Ar i = 0; i <size; i ++) {system.out.println (arr [i]);}} public void del () {size-; arr [0] = arr [9]; add_sort1 (0);} public void small (int index) {if (m <arr.length) {add_sort (index); m ++;} else {add_sort1 (index); m ++;}} public void add_sort (int index) {// 작은 상단 힙, build/ * * * * * 왼쪽 하위 노드 : 오른쪽 하위 노드 : index * 2+1 * if the the the the the the the the the the the the the the the the the the the the the the the the worl 왼쪽 자식*배열의 마지막 것도 심지어 아동 노드가 상위 노드보다 큰 경우 값 교환이 수행됩니다. 오른쪽 아동이 왼쪽 자식보다 큰 경우 값 교환이 수행됩니다.**/int par; if (index! = 0) {if (index%2 == 0) {par = (index-1)/2; if (arr [index] <arr [par]) {swap (arr, index, par); add_sort (par); arch [par*2]) {swap (par*2]) {swap (par*2)); dex] <arr [par]) {swap (arr, index, par);} add_sort (par);}} else {par = index/2; if (arr [index] <arr [par]) {adr (arr [index] <arr [par*2+1]) {swap (swap (swap) {swap (par); par*2+1); if (arr [index] <arr [par]) {swap (arr, index, par);} add_sort (par);}}} public void add_sort1 (int index) {// 작은 상단 heap/**하위 node가 부모 노드의 값보다 넓은 것처럼 맨 위를 조정하십시오*/int*2+1; max = 0; if (왼쪽 <10 && arr [왼쪽] <arr [index]) {max = left;} else {max = index;} if (오른쪽 <10 && arr [오른쪽] <arr [max]) {max = right;} if (max! = index) {swap (arr, max, index); add_sort1 (max);}} 테스트 코드; import java.util.scanner; public class main_test0 {public static void main (string args []) {스캐너 스캔 = 새 스캐너 (System.in); System.out.println ( "(작은 상단 힙) hep size를 입력하십시오 : int m = scan.nextint (); test0 = new test0 (m); {16,4,5,9,1,11,11,12,13,14,15,2,3,6,7,8}; for (int i = 0; i <a.length; i ++) {test.addtosmall (a [i]);} test.printsmall (); test.del (); test.printsmall (scan.close ();위의 Java 힙 분류 예제 (Big Top Heap, Small Top Heap)는 내가 공유하는 모든 콘텐츠입니다. 나는 당신이 당신에게 참조를 줄 수 있기를 바랍니다. 그리고 당신이 wulin.com을 더 지원할 수 있기를 바랍니다.