下标为i的节点的父节点下标:(n-2)/2 = n/2 -1
下标为i的节点的左孩子节点下标:2*i + 1
下标为i的节点的右节点下标:2*i + 2
- 先写一个堆排序
public class MergeSort {
public static void main(String[] args) {
int[] nums={1,2,3,4,5,6};
int n=nums.length;
//建堆
for (int j=(n-2)/2;j>=0;j--){ //注意这里j的初始值
motify(nums,j,n);
}
//排序
for (int j=n-1;j>=0;j--){
swap(nums,0,j);
motify(nums,0,j); //注意这里传进去的长度是j,j随循环而减小
}
}
public static void motify(int[] nums,int i,int n){
int lson=2*i+1;
int rson=2*i+2;
int max=i;
if(lson<n&&nums[lson]>nums[max]){
max=lson;
}
if(rson<n&&nums[rson]>nums[max]){
max=rson;
}
if(max!=i){
swap(nums,max,i);
motify(nums,max,n);
}
}
public static void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
2.题解一:自己实现堆排序
class Solution {
public int findKthLargest(int[] nums, int k) {
int n=nums.length;
//建堆
for (int j=(n-2)/2;j>=0;j--){
motify(nums,j,n);
}
//排序
for (int j=n-1;j>=n-k+1;j--){ //注意这里j>=n-k+1,只有这里和返回值和堆排序有区别
swap(nums,0,j);
motify(nums,0,j);
}
return nums[0];
}
public static void motify(int[] nums,int i,int n){
int lson=2*i+1;
int rson=2*i+2;
int max=i;
if(lson<n&&nums[lson]>nums[max]){
max=lson;
}
if(rson<n&&nums[rson]>nums[max]){
max=rson;
}
if(max!=i){
swap(nums,max,i);
motify(nums,max,n);
}
}
public static void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
3.题解二:使用java堆排序接口
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq=new PriorityQueue<>(Collections.reverseOrder());//创建大根堆
for(Integer i:nums){
pq.add(i);
}
while(k>1){ //当k=1时堆顶的元素就是第k大的了,终止循环
pq.poll();
k--;
}
return pq.poll();
}
}