힙 정렬
기본 소개
- 힙 정렬 힙 정렬 힙이 데이터 구조를 사용하는 알고리즘은 A에 대한 설계선택 정렬그것은이다, 그것은 또한 불안의 종류 (nlogn)입니다 O 평균 시간 복잡도, 최고, 최악의
- 힙은 다음과 같은 특성을 가진 완전 이진 트리입니다 : 각 노드의 값이 왼쪽과 오른쪽 자식 노드의 값보다 크거나, 큰 스택의 상위로 함, 평등주의는 크기의 값의 값 노드 왼쪽 자식과 오른쪽의 아이를 필요하지 않습니다
- 보다 작거나 각 노드에 대한 값은 작은 스택 최상부 불리는 그 좌측 자식 노드의 값과 동일한
4.대형 선박으로 오름차순 스택 상단, 작은 내림차순 스택 상단의 사용
기본 아이디어
... 내장 힙, 교환 ... 빌드 힙, 스택 교환 ... 빌드, 빌드 ... 교환 힙, 교환 ...
- 주문 큰 상위 스택의 순서가 될하려면
- 이 경우, 적층 체의 전체 최상위 루트 시퀀스의 최대 값은
- 마지막 요소와 교환이 시간의 끝은 최대 값이된다
- 나머지 N-1 요소는 스택 재구성. 이것은 N 개의 요소의 두 번째 최소 값이된다. 그래서 다시 실행, 정렬 순서를 얻을 수있을 것입니다
요소의 다수의 스택 최상부를 구축하는 과정에서 알 수는 서서히 감소하고, 최종적으로 정렬 된 순서를 구하는
아이디어 분석
INT에서 [] = {도착은 4,6,8,5,9} 일례로서 힙 정렬 어레이 분석
코드
package J树的提高;
import sun.misc.LRUCache;
import java.util.Arrays;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/1/9 0009 13:57
* 堆排序
*/
public class HeapSort {
public static void main(String[] args) {
//要求将数组升序排列
int[] arr = {4,6,8,5,9};
heapSort(arr);
}
//编写一个堆排序的方法
public static void heapSort(int[] arr){
int temp = 0;
System.out.println("堆排序");
//分步完成
// adjustHeap(arr,1,arr.length);
// System.out.println("第一次"+ Arrays.toString(arr));//4 9 8 5 6
//
// adjustHeap(arr,0,arr.length); //9 6 8 5 4
// System.out.println("第而次"+ Arrays.toString(arr));//9 6 8 5 4
//完成最终代码
//将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
for(int i=arr.length/2-1;i>=0;i--){
adjustHeap(arr,i,arr.length);
}
// System.out.println(Arrays.toString(arr));
//将堆顶元素与末尾元素交换,将最大元素 “沉”到数组末端
//重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序
for(int j=arr.length-1;j>0;j--){
//交换
temp = arr[j];
arr[j]=arr[0];
arr[0]=temp;
adjustHeap(arr,0,j);
}
System.out.println(Arrays.toString(arr));
}
//将一个数组(二叉树)调整成一个大顶堆
/**
* 功能:完成将以i指向对应的非叶子节点对应的树调整成大顶堆
* 举例:int[] arr = {4,6,8,5,9} ;=> i=1=>adjustHeap =>得到{4,9,8,5,6}
* 再次调用adjustHeap传入的i=0=> 得到{4,9,8,5,6}=>{9,6,8,5,4}
* @param arr 待调整的数组
* @param i 表示非叶子结点在数组中的索引
* @param length 表示对多少个元素进行调整,length在逐渐减少
*/
public static void adjustHeap(int[] arr,int i,int length){
//先取出当前元素的值,保存在临时变量
int temp = arr[i];
//开始调整
//说明
//1、k=i*2+1 k是i的左子节点
for(int k=i*2+1;k<length;k=k*2+1){
//找左右节点哪个节点大
if(((k+1)<length) && (arr[k]<arr[k+1])){//说明左子节点值小于右子节点的值
k++; //k指向右子节点
}
if(arr[k]>temp){//如果子节点大于父节点
arr[i]=arr[k]; //把较大的值赋给当前节点
i=k;//让i指向k,继续循环比较
}else{
break; //从左到右从下到上调整
}
}
//当for循环结束后,我们已经将i为父节点的树最大值,放在了最顶(局部)
arr[i]=temp;//将temp值放到调整后的位置
}
}